Compare commits

...
455 Commits
Author SHA1 Message Date
Mr Chen 4769ce5be8 Merge pull request #431 from midoks/dev
0.15.2
2023-08-05 15:12:37 +08:00
midoks 8e16cbf7f9 0.15.2 2023-08-05 15:06:22 +08:00
midoks 4225d4c040 Update common.py 2023-08-05 14:43:14 +08:00
midoks b578f2fddc Update common.py 2023-08-05 14:42:43 +08:00
midoks 961c3423fd Update common.py 2023-08-05 14:29:52 +08:00
midoks 8040c8c67a Update common.py 2023-08-05 14:21:25 +08:00
midoks 5aca7d7c26 Update common.py 2023-08-05 14:17:16 +08:00
midoks d9f99e6b7c Update common.py 2023-08-05 14:17:01 +08:00
midoks 3addb46708 Update common.py 2023-08-05 13:46:19 +08:00
midoks e6b493237d 优化初始化安装SSH端口识别 2023-08-05 13:36:13 +08:00
midoks 7f42054a14 Update ubuntu.sh 2023-08-05 12:29:39 +08:00
midoks 501af3da15 Update plugins_api.py 2023-08-05 12:01:46 +08:00
midoks 68727cbe91 Update site_api.py 2023-08-05 11:28:33 +08:00
midoks c5207961f3 Update index.py 2023-08-05 01:52:49 +08:00
midoks a04e05c7e8 Update index.py 2023-08-05 01:19:42 +08:00
midoks 5b8cca24aa Update index.py 2023-08-05 00:46:41 +08:00
midoks cafe58f3fc Update index.py 2023-08-05 00:45:04 +08:00
midoks d1e2781eb9 Update index.py 2023-08-05 00:44:48 +08:00
midoks 67c899fc84 Update index.py 2023-08-05 00:43:06 +08:00
midoks 7432548ff9 Update index.py 2023-08-05 00:24:35 +08:00
midoks 0c2c136097 Update index.py 2023-08-04 23:58:21 +08:00
midoks 2a7e21951b Update my8.0.cnf 2023-08-04 22:49:18 +08:00
midoks 066185e404 网站设置反向代理升级功能 2023-08-04 20:27:20 +08:00
midoks bd431f1647 docker阶段性完成 2023-08-03 18:37:14 +08:00
midoks 0a6e88d81d update 2023-08-03 17:00:12 +08:00
midoks 02c9988ef7 Update docker.js 2023-08-03 00:24:13 +08:00
midoks 5ee7df4a46 Update nginx.conf 2023-08-03 00:14:16 +08:00
midoks 5f382c0034 update 2023-08-03 00:06:01 +08:00
midoks 63d17c4d77 Update docker.js 2023-08-02 23:24:10 +08:00
midoks 38722c1dc2 Update index.py 2023-08-02 17:51:29 +08:00
midoks ea982b7261 Update README.md 2023-08-02 17:50:22 +08:00
midoks 73d9edced8 使用mariadb二进制导入备份文件 2023-08-02 17:36:27 +08:00
midoks af03c004a3 Update rsyncd.js 2023-08-02 15:35:30 +08:00
midoks ddd9e70ac2 Update rsyncd.js 2023-08-02 15:29:32 +08:00
midoks 8976a7a147 Update rsyncd.js 2023-08-02 15:26:55 +08:00
midoks 677ff8ec0c Update README.md 2023-08-02 15:10:42 +08:00
midoks 47d240e2b8 rsyncd添加优化 2023-08-02 15:10:23 +08:00
midoks 1f7bd76875 Update crontab_api.py 2023-08-02 14:27:04 +08:00
midoks f04c70f022 计划任务自动脚本运行时间 2023-08-02 14:04:00 +08:00
midoks 5044cc5db9 Update README.md 2023-08-02 00:06:51 +08:00
midoks 4329b90ac4 Update info.json 2023-08-01 23:58:10 +08:00
midoks f7873b6dcd Update init_cmd.py 2023-07-25 00:03:20 +08:00
midoks a80d666786 update 2023-07-24 23:52:38 +08:00
Mr Chen 0598704dce Merge pull request #428 from midoks/dev
修复centos9源安装问题
2023-07-22 12:54:17 +08:00
midoks 8f19a05755 Update rhel.sh 2023-07-22 12:53:07 +08:00
midoks f320d7cc69 Update rhel.sh 2023-07-22 12:26:56 +08:00
midoks 1e97929a24 Update push_notice_msg.py 2023-07-21 12:10:55 +08:00
Mr Chen c66bbac97e Merge pull request #427 from midoks/dev
python3.7 urllib3在亚马逊降级
2023-07-20 16:14:22 +08:00
midoks 1f7a0d2795 Create r3.7.txt 2023-07-20 16:04:18 +08:00
midoks f05ce79e63 Update rhel.sh 2023-07-20 15:55:11 +08:00
midoks 9f3d06191a PHP提示优化 2023-07-19 18:35:27 +08:00
Mr Chen 2c6614a5ff Merge pull request #426 from midoks/dev
赞助换域名
2023-07-18 15:23:49 +08:00
midoks 905bad29cf Update README.md 2023-07-18 15:22:19 +08:00
midoks 9ba572a8ce AD修改 2023-07-16 17:23:45 +08:00
Mr Chen 85fc333d2c Merge pull request #424 from midoks/dev
0.15.1
2023-07-15 23:04:39 +08:00
midoks 5bc27a4725 Update config_api.py 2023-07-15 22:53:38 +08:00
midoks e5acf206f5 Update cli.sh 2023-07-15 20:43:13 +08:00
midoks ae7afc2eb5 Update rhel.sh 2023-07-15 20:34:46 +08:00
midoks 5c8527a5de 监控页面-自定义时间优化。 2023-07-15 19:33:17 +08:00
midoks 274592229e Update rhel.sh 2023-07-15 15:51:03 +08:00
midoks 60ddb13f8e Update rhel.sh 2023-07-15 15:50:35 +08:00
midoks f62af00fb7 Update rhel.sh 2023-07-15 15:49:28 +08:00
midoks 9c6faefffd Update rhel.sh 2023-07-15 15:38:14 +08:00
midoks c9e27c2add 优化
* [插件]docker - 添加IP地址池。
* PHP下载中国优化。
2023-07-15 15:00:00 +08:00
midoks 97b1e8b9b3 Update rhel.sh 2023-07-15 12:34:47 +08:00
midoks 18cdcd1436 修复子目录绑定-伪静态问题。 2023-07-13 10:36:16 +08:00
midoks 7d783c64b6 OP防火墙优化
站点配置-状态关闭后,不再防御。
2023-07-13 00:40:46 +08:00
midoks 0b65d69750 Update __init__.py 2023-07-12 22:18:55 +08:00
midoks 693dbb8cf1 Update __init__.py 2023-07-12 22:17:58 +08:00
midoks 117a99e729 增加标识 2023-07-12 09:46:58 +08:00
midoks 45d4b8a5de update 2023-07-11 16:25:34 +08:00
midoks a5791051b1 Update debian.sh 2023-07-11 16:11:20 +08:00
midoks dc3f8f8e0b 自动同步gitee 2023-07-11 12:21:48 +08:00
midoks bf1d00c012 Update config_api.py 2023-07-10 22:41:13 +08:00
midoks 51cf851cea Update site.js 2023-07-10 22:38:37 +08:00
midoks 1e09408eb9 Update index.py 2023-07-10 22:13:46 +08:00
midoks 7659865caf Update lib.sh 2023-07-05 22:19:44 +08:00
Mr Chen ad1851d068 Merge pull request #423 from midoks/dev
requests兼容低版本
2023-07-05 18:05:33 +08:00
midoks e174652afc Update requirements.txt 2023-07-05 18:02:40 +08:00
midoks a95e7aacd7 Update r3.6.txt 2023-07-05 18:00:36 +08:00
Mr Chen 6aa638ef9a Merge pull request #422 from midoks/dev
Update requirements.txt
2023-07-05 13:03:14 +08:00
midoks 6f3d50bae5 Update requirements.txt 2023-07-05 13:01:08 +08:00
Mr Chen 301a5a95b8 Merge pull request #421 from midoks/dev
AD
2023-07-05 12:51:37 +08:00
midoks d35b9dccc7 AD信息 2023-07-05 12:49:47 +08:00
midoks 82680605ac mvirtua ad 2023-07-05 12:47:05 +08:00
midoks 5b148b3d1a Update requirements.txt 2023-07-05 10:20:04 +08:00
Mr Chen 714acd20e5 Merge pull request #420 from midoks/dev
0.15.0
2023-07-04 20:55:21 +08:00
midoks bf58cd8acc Update config_api.py 2023-07-04 20:52:57 +08:00
midoks 059053d27c mysql安装成功后,删除原文件 2023-07-03 22:22:11 +08:00
midoks 185e73c26a Update index.py 2023-07-03 22:12:55 +08:00
midoks 569511d321 update 2023-07-03 22:08:00 +08:00
midoks f88bf5059f Update README.md 2023-07-03 17:52:56 +08:00
midoks 05b63b8d2b Update index.py 2023-07-03 17:45:12 +08:00
midoks 3a197b273d Update docker.js 2023-07-03 17:37:14 +08:00
midoks f4fdbab41c Update index.py 2023-07-03 17:35:34 +08:00
midoks f6b2940657 docker插件容器创建OK 2023-07-03 17:34:58 +08:00
midoks 78b9ac5df0 up 2023-07-03 11:53:54 +08:00
midoks 3ea4272307 Update docker.js 2023-07-02 16:29:10 +08:00
midoks efc7cee9ad Update docker.js 2023-07-02 15:36:38 +08:00
midoks 5c4805453d Update docker.js 2023-07-02 15:27:25 +08:00
midoks f6da241c85 update 2023-07-02 14:38:56 +08:00
midoks d5b6eb2325 update 2023-07-01 22:06:54 +08:00
midoks 6ed2cddf71 Update docker.js 2023-07-01 21:35:46 +08:00
midoks 9c31d76442 docker update 2023-07-01 21:34:04 +08:00
midoks 7aecbaf7df Update docker.js 2023-07-01 15:22:41 +08:00
midoks ee81a86d24 update 2023-07-01 15:17:43 +08:00
midoks 0a60d66732 update 2023-07-01 14:46:22 +08:00
midoks c3e3cff472 Update docker.js 2023-07-01 12:37:15 +08:00
midoks 194d46eb6a Update docker.js 2023-07-01 12:37:02 +08:00
midoks d66bc94edc Update docker.js 2023-07-01 12:34:09 +08:00
midoks fb4ffcd343 Update index.py 2023-07-01 12:30:58 +08:00
midoks 10c235e317 Update r3.6.txt 2023-07-01 12:25:32 +08:00
midoks 9c156928d8 up 2023-07-01 12:24:04 +08:00
midoks 771905d7f6 Update requirements.txt 2023-07-01 12:23:01 +08:00
midoks cd21b3f3e7 Update r3.6.txt 2023-07-01 12:22:18 +08:00
midoks 982026db24 update 2023-07-01 12:21:07 +08:00
midoks f9b91d9989 Update docker.js 2023-07-01 12:17:30 +08:00
midoks f7b1159bd7 update 2023-07-01 12:15:51 +08:00
midoks 6aa49ddbcf Update rhel.sh 2023-07-01 11:48:06 +08:00
midoks 866eddac1d Update lib.sh 2023-07-01 10:19:42 +08:00
midoks af0cce4216 Update install.sh 2023-07-01 10:16:39 +08:00
midoks 3951322d86 Update install_dev.sh 2023-07-01 10:16:23 +08:00
midoks dfdd16b444 Update index.py 2023-07-01 10:11:15 +08:00
midoks aa8fec2b7e update 2023-07-01 09:52:53 +08:00
midoks 2a8958ab84 Update index.py 2023-07-01 00:32:36 +08:00
midoks f5125670ee Update index.py 2023-07-01 00:19:24 +08:00
midoks 2a8d4fb7a9 Update requirements.txt 2023-07-01 00:14:04 +08:00
midoks 59f7fe2290 Update requirements.txt 2023-07-01 00:07:30 +08:00
midoks 928db6e7e7 Update requirements.txt 2023-07-01 00:02:13 +08:00
midoks f3927bd6cf Update requirements.txt 2023-07-01 00:01:32 +08:00
midoks bb92727b56 Update requirements.txt 2023-07-01 00:00:14 +08:00
midoks 21b80b1fce Update index.py 2023-06-30 23:54:05 +08:00
midoks 637da92834 up 2023-06-30 23:43:51 +08:00
midoks f5859626a9 update 2023-06-30 21:57:42 +08:00
midoks 003449eb0a update 2023-06-30 12:30:28 +08:00
midoks d27f926191 update 2023-06-30 12:16:25 +08:00
midoks 7483247d4d up 2023-06-30 10:17:02 +08:00
midoks 1ad841d3af Update docker.js 2023-06-30 00:09:15 +08:00
midoks 27376d879c up 2023-06-30 00:09:09 +08:00
midoks 8b824447c1 Update php.service.tpl 2023-06-29 18:29:39 +08:00
midoks a1d26dcd45 Update intl.sh 2023-06-29 16:25:12 +08:00
midoks 5e68c7bf0a Update install.sh 2023-06-29 13:00:08 +08:00
midoks 481ae16713 Update index.py 2023-06-29 12:59:05 +08:00
midoks 2d2bd39f9e Update intl.sh 2023-06-29 12:02:48 +08:00
midoks 7246a878a5 Update intl.sh 2023-06-29 12:00:37 +08:00
midoks 542ee3cdb0 Update intl.sh 2023-06-29 11:59:59 +08:00
midoks 69503b223b update 2023-06-29 11:43:56 +08:00
midoks 78d8fa7ebf Update lib.sh 2023-06-29 10:54:26 +08:00
midoks 21e9d8f2d8 Update update_dev.sh 2023-06-29 10:49:10 +08:00
midoks 3c6adfbd44 Update install.sh 2023-06-29 10:41:10 +08:00
midoks c0e70abe6d Update install_dev.sh 2023-06-29 10:40:31 +08:00
midoks f174e71228 Update app.py 2023-06-29 10:25:14 +08:00
midoks 7a9a811ea6 Update app.py 2023-06-29 10:21:39 +08:00
midoks c7e3d9d9a3 Update app.py 2023-06-29 10:20:39 +08:00
midoks 161f7a1bc0 Update app.py 2023-06-29 10:18:52 +08:00
midoks 175cce0131 Update lib.sh 2023-06-29 10:11:52 +08:00
midoks 3735897ed2 Update lib.sh 2023-06-29 09:59:06 +08:00
midoks 30bfa5a630 Update lib.sh 2023-06-29 09:56:24 +08:00
midoks 594fdb4712 Update lib.sh 2023-06-29 09:55:14 +08:00
midoks 31a441ea02 update 2023-06-29 09:52:30 +08:00
midoks 06f7087fad Update requirements.txt 2023-06-29 09:30:06 +08:00
midoks e7b8f5afdc Update index.py 2023-06-29 09:25:55 +08:00
midoks 6b57addfa7 Update index.py 2023-06-28 19:11:44 +08:00
midoks aea435fbaf Update index.py 2023-06-28 18:53:45 +08:00
midoks 9cd6656946 u 2023-06-28 16:04:17 +08:00
midoks 4f7df4b3c3 Update index.py 2023-06-28 14:58:45 +08:00
midoks 70d12b7b8d docker 2023-06-28 14:53:59 +08:00
midoks fe576c820a Update requirements.txt 2023-06-28 04:09:09 +08:00
midoks b48a53e0d7 Create nezha.conf 2023-06-28 04:04:44 +08:00
midoks 4701839c33 up 2023-06-28 03:40:23 +08:00
midoks 916bc67c4d Update cert_api.py 2023-06-28 03:21:11 +08:00
midoks d7bba830cc Update requirements.txt 2023-06-28 02:33:11 +08:00
midoks 7a28f8f57a Update index.py 2023-06-28 02:30:28 +08:00
midoks 41ee25aa7b update 2023-06-28 02:21:59 +08:00
midoks c8aa91cfa3 up 2023-06-28 02:09:28 +08:00
midoks 98f27498b0 Update index.py 2023-06-28 01:57:06 +08:00
midoks 5444fe6455 Update index.py 2023-06-28 01:40:41 +08:00
midoks 9627c6e47b Update index.py 2023-06-28 01:32:14 +08:00
midoks 13597d6282 Update index.py 2023-06-28 01:21:15 +08:00
midoks d09494e3aa Update index.py 2023-06-28 01:14:15 +08:00
midoks d35439d286 Update index.py 2023-06-28 01:14:03 +08:00
midoks ced48bab47 nezha 测试OK 2023-06-28 01:02:58 +08:00
midoks fe2df6cc8d up 2023-06-28 00:08:38 +08:00
midoks 8bdfe15101 nezha 60% 2023-06-28 00:04:07 +08:00
midoks 42e9983b88 Update config.json 2023-06-27 15:56:43 +08:00
midoks 9b7c0b6f99 up 2023-06-27 15:11:38 +08:00
midoks e421292c9e up 2023-06-27 14:13:04 +08:00
midoks 7b4d31779a Update install.sh 2023-06-27 01:31:52 +08:00
midoks f3b09056f3 init nezha plugin 2023-06-26 23:06:06 +08:00
midoks a92ccea6c5 lrzsz 2023-06-26 11:57:07 +08:00
midoks 9da77a0a9b up 2023-06-24 22:37:02 +08:00
midoks c233ecaaa7 up 2023-06-22 16:06:04 +08:00
midoks 5828b8b8cb up 2023-06-22 16:00:09 +08:00
midoks a4a1a2c83c up 2023-06-20 16:39:36 +08:00
midoks 0e20bc182c up 2023-06-19 20:28:44 +08:00
midoks 99c0b0a81a Update site_api.py 2023-06-17 23:20:24 +08:00
midoks 3fa199fec4 acme部署问题 2023-06-17 23:18:15 +08:00
midoks 194c36c6d8 tg ad 2023-06-15 01:43:21 +08:00
midoks 2fb542f6b4 Update all_test.sh 2023-06-14 01:25:55 +08:00
midoks 60af43ed31 Update intl.sh 2023-06-14 01:24:15 +08:00
midoks 9f02cf9744 Update install.sh 2023-06-14 01:21:47 +08:00
midoks 846bd270df Update yaf.sh 2023-06-14 01:14:47 +08:00
midoks d910d4f462 up 2023-06-14 00:31:20 +08:00
midoks 13f5b1bf02 up 2023-06-13 18:34:57 +08:00
midoks 1fc3fd6247 Update lib.sh 2023-06-13 18:03:53 +08:00
midoks 36e3feb886 Update requirements.txt 2023-06-13 17:46:00 +08:00
midoks 0ca34afacd Update lib.sh 2023-06-13 17:43:39 +08:00
midoks ffb3288f3d Update requirements.txt 2023-06-13 17:40:55 +08:00
midoks e2f68a73ed Update requirements.txt 2023-06-13 17:34:23 +08:00
midoks 92fa8da2f6 Update lib.sh 2023-06-13 17:19:23 +08:00
midoks 7c96ddd63e Update lib.sh 2023-06-13 17:14:50 +08:00
midoks c4e7872179 Update lib.sh 2023-06-13 17:14:31 +08:00
midoks d399cb2bb4 Update install.sh 2023-06-13 16:38:04 +08:00
midoks 985cbc7eca Update install.sh 2023-06-13 16:36:48 +08:00
midoks 27ed21a17d update 2023-06-10 15:09:31 +08:00
midoks 972165ba1a Update lib.sh 2023-05-30 17:53:16 +08:00
midoks e76eb4d0e8 Update client_check_member.py 2023-05-29 18:40:12 +08:00
midoks fd05c40dbb up 2023-05-29 18:34:37 +08:00
midoks a1a7fa5c82 网站备注优化 2023-05-28 19:59:31 +08:00
midoks 531de1407f Update push_notice_msg.py 2023-05-28 19:00:42 +08:00
midoks ca455f13e8 ad 2023-05-28 14:50:53 +08:00
midoks ab5342b01f Update docker.js 2023-05-27 00:18:44 +08:00
midoks a5a57c5718 update 2023-05-27 00:18:39 +08:00
midoks 27999b21e6 Update config.json 2023-05-24 23:04:59 +08:00
midoks d2c6caeef2 Update client_temp.py 2023-05-23 20:46:32 +08:00
midoks de30d8a41f Create client_temp.py 2023-05-23 20:42:08 +08:00
midoks d3abc8e7b2 up 2023-05-18 17:10:50 +08:00
midoks b7aad65eb5 Update site_api.py 2023-05-17 13:36:35 +08:00
midoks 240b1dec27 修正网站搜索功能 2023-05-16 20:34:12 +08:00
midoks 4756e0f68b Update push_notice_msg.py 2023-05-15 19:30:38 +08:00
midoks 59f62b948a Update push_notice_msg.py 2023-05-15 19:30:00 +08:00
midoks 0ab0741031 up 2023-05-15 19:23:32 +08:00
midoks 2fd2f6e844 AD 2023-05-15 19:20:58 +08:00
midoks e534c6177a update 2023-05-15 19:14:43 +08:00
midoks 897c6322fc Update install.sh 2023-05-14 23:57:41 +08:00
midoks 201e93f946 Update requirements.txt 2023-05-14 19:09:02 +08:00
Mr Chen a78fd957ec Merge pull request #411 from midoks/dev
更新pip库2
2023-05-14 19:05:30 +08:00
midoks 3ce037b0a1 Update requirements.txt 2023-05-14 19:03:39 +08:00
midoks f3176340f8 Update requirements.txt 2023-05-14 19:02:58 +08:00
midoks 7bfe096e8d Update requirements.txt 2023-05-14 19:00:45 +08:00
Mr Chen 066428fca8 Merge pull request #410 from midoks/dev
更新pip版本
2023-05-14 18:46:51 +08:00
midoks a1313846c8 Update requirements.txt 2023-05-14 18:43:47 +08:00
midoks 0433123abd Update requirements.txt 2023-05-14 18:36:50 +08:00
midoks 72e99844dd Update requirements.txt 2023-05-14 18:31:19 +08:00
Mr Chen 3a7882e7fa Merge pull request #409 from midoks/dev
0.14.5
2023-05-14 13:12:27 +08:00
midoks bec2a9a12c 0.14.5
* 软件管理-搜索功能。
* 文件-右键功能优化。
2023-05-14 13:10:17 +08:00
midoks 8f02363782 Update files.html 2023-05-12 11:22:38 +08:00
midoks 939c847f3e Update plugins_api.py 2023-05-10 18:23:06 +08:00
midoks a623039db7 完成搜索功能 2023-05-10 18:20:48 +08:00
midoks b7f49a1839 Update soft.html 2023-05-10 17:59:17 +08:00
midoks f1f60870f6 up 2023-05-09 12:46:09 +08:00
midoks 3b04739fd4 up 2023-05-09 12:45:25 +08:00
midoks fdf1e0b0be up 2023-05-09 12:39:44 +08:00
midoks d3385f526f Update client_check_member.py 2023-05-09 11:37:39 +08:00
midoks 20f9095b93 up 2023-05-09 09:17:54 +08:00
midoks 757cf483a2 Update client_ad.py 2023-05-08 12:07:36 +08:00
midoks 1712cfd024 Update client_ad.py 2023-05-08 12:03:16 +08:00
midoks 2b524cbe75 Update client_ad.py 2023-05-08 11:57:01 +08:00
midoks 607d384000 Update client_ad.py 2023-05-08 11:29:09 +08:00
midoks 14cdc7b82e Update client_ad.py 2023-05-08 11:15:27 +08:00
midoks c3219bcba2 Update client_check_member.py 2023-05-07 23:15:06 +08:00
Mr Chen a12c4dd78e Merge pull request #407 from midoks/dev
0.14.4
2023-05-06 14:54:52 +08:00
midoks 39c6f19592 Update README.md 2023-05-06 14:54:34 +08:00
midoks f18c05a097 0.14.4 2023-05-06 14:53:16 +08:00
midoks 80f296ea19 redat 系列 php74之后都需要安装oniguruma
debian系统,不需要
2023-05-06 14:42:54 +08:00
midoks b3e9283a58 Update rhel.sh 2023-05-06 14:37:25 +08:00
midoks 2e140a3ae1 Update index.py 2023-05-06 14:18:46 +08:00
midoks 4d733c8886 Update index.py 2023-05-06 14:16:50 +08:00
midoks 62a7320baf Update rhel.sh 2023-05-06 13:59:02 +08:00
midoks 3dc7c2f5c1 Update rhel.sh 2023-05-06 13:52:55 +08:00
midoks fe62bbee06 Update rhel.sh 2023-05-06 13:24:47 +08:00
midoks f7c0cd82a0 Update rhel.sh 2023-05-06 13:22:49 +08:00
midoks 13a2014558 Update rhel.sh 2023-05-06 12:49:25 +08:00
midoks 5981f94376 Update rhel.sh 2023-05-06 12:30:51 +08:00
midoks 005e0f1513 Update rhel.sh 2023-05-06 12:27:54 +08:00
midoks 63a0f0fbdc Update rhel.sh 2023-05-05 23:32:07 +08:00
midoks edc0be11a1 Update rhel.sh 2023-05-05 23:22:22 +08:00
midoks 908b6e67c6 Update rhel.sh 2023-05-05 23:21:57 +08:00
midoks dfe46332db up 2023-05-05 22:49:39 +08:00
midoks fcdf2e18b2 Update config_api.py 2023-05-05 22:19:33 +08:00
midoks 3c8f9bcf96 Update config.js 2023-05-05 22:19:26 +08:00
midoks ebadd6d80d 端口修改后,跳转优化 2023-05-05 22:16:53 +08:00
Mr Chen 6062699074 Merge pull request #406 from midoks/dev
0.14.3
2023-05-05 20:52:04 +08:00
midoks df9d57ba70 Update README.md 2023-05-05 20:50:20 +08:00
midoks ffca953539 up 2023-05-05 20:49:45 +08:00
midoks bd4946124f Update install.sh 2023-05-05 18:21:10 +08:00
midoks 8e18c63cee up 2023-05-05 17:52:13 +08:00
midoks d201ca2574 Update install_dev.sh 2023-05-05 17:51:09 +08:00
midoks b644f91090 安装时curl库软连接修复 2023-05-05 16:59:47 +08:00
midoks 931f51cf59 Update client_ad.py 2023-05-05 14:12:14 +08:00
midoks 0909a11fd9 Update client_ad.py 2023-05-05 14:03:45 +08:00
midoks 2ba2833699 Update client_ad.py 2023-05-05 13:59:14 +08:00
midoks 20389263fb Update client_ad.py 2023-05-04 20:41:10 +08:00
midoks 86141ccf3a Update my5.7.cnf 2023-05-04 16:42:59 +08:00
midoks b2fdf84ca0 Update index.py 2023-05-04 16:39:46 +08:00
midoks 8fbc456e1a Update my5.7.cnf 2023-05-04 13:19:21 +08:00
midoks 4e43382496 Update client_ad.py 2023-05-03 18:29:37 +08:00
midoks 0326d4f112 Update client_ad.py 2023-05-03 18:05:33 +08:00
midoks a87c13c5e0 Update client_ad.py 2023-05-03 13:02:21 +08:00
midoks 5f3720c855 Update client_ad.py 2023-05-03 12:50:41 +08:00
midoks f548e020c4 up 2023-05-03 12:33:56 +08:00
midoks 7f21781c0b Update tgclient.py 2023-05-03 12:33:01 +08:00
midoks 680b0f09f2 Update client_ad.py 2023-05-03 12:22:31 +08:00
midoks 482943a63c Update client_ad.py 2023-05-03 10:53:49 +08:00
midoks 2871aee18e Create client_ad.py 2023-05-03 10:53:18 +08:00
midoks ff46d9b36e up 2023-05-02 21:39:18 +08:00
midoks fd5fcba543 up 2023-05-02 13:25:07 +08:00
Mr Chen fe04e02e88 Merge pull request #405 from midoks/dev
0.14.2
2023-05-02 12:11:48 +08:00
midoks 93554332a7 Update README.md 2023-05-02 12:10:37 +08:00
midoks b541c7e1b7 Update config_api.py 2023-05-02 12:09:02 +08:00
midoks 1dec1a286a Update docker.js 2023-05-02 12:07:51 +08:00
midoks b17510104d up 2023-05-02 11:55:32 +08:00
midoks c2c8ea0ce6 Update install.sh 2023-05-02 11:52:56 +08:00
midoks acbdb013ae Update install.sh 2023-05-02 11:42:16 +08:00
midoks b025f21765 Update index.py 2023-05-02 11:36:28 +08:00
midoks 1afc8a69e5 Update index.py 2023-05-02 11:35:21 +08:00
midoks 743fc9e8d3 Update index.py 2023-05-02 11:35:06 +08:00
midoks 8d692d2b3b Update install.sh 2023-05-02 11:34:00 +08:00
midoks a0b362e691 Update index.py 2023-05-02 11:31:25 +08:00
midoks 98e1c2ae8f Update install.sh 2023-05-02 11:26:27 +08:00
midoks c0e5915285 Update index.html 2023-05-02 11:23:46 +08:00
midoks 667a0fd0fd Update install.sh 2023-05-02 11:19:03 +08:00
midoks 8ed5f283b0 Update client_check_member.py 2023-05-01 17:30:03 +08:00
midoks 643c370d30 up 2023-05-01 17:26:02 +08:00
midoks 4601303065 up 2023-05-01 16:05:54 +08:00
midoks 14940d6734 Delete mdioks.session 2023-05-01 15:09:14 +08:00
midoks fdc2b0f5c4 Update client_holding.py 2023-05-01 15:08:40 +08:00
midoks cf0b233f63 Update client_check_member.py 2023-05-01 14:51:54 +08:00
midoks b3a7ef2206 Create client_holding.py 2023-05-01 14:49:50 +08:00
midoks 9a3ca3e833 Update index.html 2023-04-30 10:17:28 +08:00
midoks 9afff8df3f Update index.py 2023-04-30 01:13:00 +08:00
midoks ccd0b06223 Update tgclient.py 2023-04-30 01:04:16 +08:00
midoks 7b495fe9bf Update tgclient.py 2023-04-29 16:24:19 +08:00
midoks 2c3fb75e8f Update tgclient.js 2023-04-29 16:11:09 +08:00
midoks 53b606602f up 2023-04-29 16:10:30 +08:00
midoks ecef0cf994 up 2023-04-29 16:01:10 +08:00
midoks 3691d41b23 Update client_change_username.py 2023-04-28 21:47:13 +08:00
midoks 1f66457a3e Update client_change_username.py 2023-04-28 17:25:38 +08:00
midoks 8e05beccfd Update tgclient.py 2023-04-28 17:22:56 +08:00
midoks 35424eae1f up 2023-04-28 17:21:13 +08:00
midoks ed6df6d527 up 2023-04-28 17:03:41 +08:00
midoks 4366c4afde Update tgclient.py 2023-04-24 22:05:34 +08:00
midoks 4bb059f62f Update info.json 2023-04-24 21:23:44 +08:00
midoks aa8f618d9c Update tgclient.py 2023-04-24 21:15:47 +08:00
midoks dfd753e4c1 up 2023-04-24 21:07:25 +08:00
midoks e38daf3c89 Update tgclient.py 2023-04-24 20:51:54 +08:00
midoks 535838fc5e Update tgclient.py 2023-04-24 20:44:28 +08:00
midoks 797853bd61 Update tgclient.py 2023-04-24 20:36:49 +08:00
midoks 0de3aff045 up 2023-04-24 20:32:41 +08:00
midoks 0b7b48ab23 up 2023-04-24 20:31:31 +08:00
midoks 5ff0a0bfbc Update index.py 2023-04-21 21:03:30 +08:00
midoks 9131f44d67 Update install.sh 2023-04-21 13:02:42 +08:00
midoks 6b86bb9d2b Update docker.js 2023-04-21 13:00:05 +08:00
midoks dc06d6beda Update install.sh 2023-04-21 12:58:50 +08:00
midoks 2c8ea2498e Update install.sh 2023-04-21 12:55:38 +08:00
midoks 6b01173b61 Update push_notice_msg.py 2023-04-20 12:41:56 +08:00
midoks 883c554850 up 2023-04-20 12:19:33 +08:00
midoks d267da351c Update push_ad.py 2023-04-16 23:48:24 +08:00
midoks 13a39f4d6a up 2023-04-16 20:50:30 +08:00
Mr Chen cff1d5ee89 Merge pull request #403 from midoks/dev
0.14.1
2023-04-16 20:42:39 +08:00
midoks bf5274c313 0.14.1
* 安装优化。
* 加入OP负载均衡插件。
* 网站防篡改程序(测试中)。
2023-04-16 20:41:39 +08:00
midoks 5623e3efac Update requirements.txt 2023-04-16 20:38:03 +08:00
midoks b93bb6c64c Update requirements.txt 2023-04-16 20:37:24 +08:00
midoks c9962f169e Update requirements.txt 2023-04-16 20:36:01 +08:00
midoks 080f343ee2 Update push_ad.py 2023-04-15 10:57:19 +08:00
midoks 5aeaf13f16 负载均衡插件 2023-04-13 15:42:01 +08:00
midoks 528094cfa7 网站防篡改程序 2023-04-13 15:33:15 +08:00
midoks ed3e3336b2 Update push_notice_msg.py 2023-04-13 15:28:38 +08:00
Mr Chen a75a49c2ae Merge pull request #402 from midoks/dev
0.14.0
2023-04-13 15:21:19 +08:00
midoks 1204e72f41 0.14.0
* 加入系统加固插件。
2023-04-13 15:20:15 +08:00
midoks 13ca5544a5 Update system_safe.tpl 2023-04-13 15:14:32 +08:00
midoks e53fe26d52 Update system_safe.tpl 2023-04-13 15:09:20 +08:00
midoks 13772399f6 Update system_safe.py 2023-04-13 15:05:06 +08:00
midoks 98f11e2662 Update plugins_api.py 2023-04-13 14:49:46 +08:00
midoks f0b0302f75 Update install.sh 2023-04-13 14:42:07 +08:00
midoks 5b9b466cb9 系统加固放出 2023-04-13 14:39:18 +08:00
midoks 5588a11ea5 Update cert_request.py 2023-04-10 22:35:09 +08:00
midoks da05a4ef19 up 2023-04-10 22:34:12 +08:00
midoks 34cf899529 Update mw.py 2023-04-04 12:43:09 +08:00
midoks 0d7d67b012 up 2023-04-04 12:42:47 +08:00
midoks 5b778bfc0d Update vip_api.py 2023-04-04 12:20:28 +08:00
midoks 6ce414cecf up 2023-04-03 22:39:07 +08:00
midoks c8160b63e7 up 2023-04-03 22:30:08 +08:00
midoks 68d957fd6e Update README.md 2023-04-03 19:34:05 +08:00
midoks f09c438500 Update config.html 2023-04-03 17:46:18 +08:00
Mr Chen 9bc9944a3e Merge pull request #401 from midoks/dev
0.13.6
2023-04-03 17:43:58 +08:00
midoks 9e4c2b13d5 Update README.md 2023-04-03 17:43:05 +08:00
midoks cd7143047f 0.13.6
1.修复初始化安装,缺少解压命令。
2.加入aes加密/解密方法
2023-04-03 17:41:48 +08:00
midoks d608ac4d94 Update install.sh 2023-04-03 16:48:53 +08:00
midoks 9fedf9d10d Update push_notice_msg.py 2023-04-01 10:37:33 +08:00
midoks 9936191da2 up 2023-04-01 10:35:54 +08:00
midoks 538eba3acf up 2023-03-31 22:37:40 +08:00
midoks e39ee9a6f7 VIP用户管理 2023-03-30 21:57:33 +08:00
Mr Chen e1820ad5b3 Merge pull request #400 from midoks/dev
0.13.5
2023-03-30 17:31:54 +08:00
midoks 22133f1a6c 0.13.5
### 版本更新 0.13.5

* 添加邮件通知功能。
* 修复初始安装脚本。
2023-03-30 17:30:15 +08:00
midoks 0041cbdff3 添加邮件通知功能 2023-03-30 17:18:40 +08:00
midoks 889da3c769 Update install.sh 2023-03-30 11:59:55 +08:00
midoks d086eb9c61 Update install.sh 2023-03-30 11:56:48 +08:00
midoks 832fa9cd1a Update install_dev.sh 2023-03-30 11:54:40 +08:00
midoks 8c19fb9629 Update config_api.py 2023-03-30 11:22:36 +08:00
midoks a2e4dd6753 Update push_notice_msg.py 2023-03-30 11:22:19 +08:00
midoks 22ba7dda55 Update install.sh 2023-03-29 16:35:09 +08:00
midoks 2ffa36eecb up 2023-03-29 16:32:46 +08:00
Mr Chen fe5843b35d Merge pull request #398 from midoks/dev
修复python pip源安装
2023-03-29 16:27:46 +08:00
midoks e95acbe947 Update lib.sh 2023-03-29 16:08:55 +08:00
midoks aed8319dd3 Update push_ad.py 2023-03-29 14:08:06 +08:00
midoks babe1b885e Update push_notice_msg.py 2023-03-29 13:17:38 +08:00
midoks 0612f52402 Update push_notice_msg.py 2023-03-29 13:03:52 +08:00
midoks db67cea737 AD 2023-03-29 13:01:12 +08:00
midoks 52cf675843 Update install_dev.sh 2023-03-29 08:49:26 +08:00
Mr Chen 3421bf6ab5 Merge pull request #397 from midoks/dev
0.13.4
2023-03-28 23:54:51 +08:00
midoks 2f39bd600b Update config_api.py
### 版本更新 0.13.4

无重大更新

* 国内安装不在依赖gitee。
* tgbot优化。
2023-03-28 23:53:14 +08:00
midoks acd5ec69e8 Update tgbot.py 2023-03-28 23:49:59 +08:00
midoks 09878728af Update push_ad.py 2023-03-28 20:25:09 +08:00
midoks af82e9f129 Update push_notice_msg.py 2023-03-28 20:23:08 +08:00
midoks c74630e738 Update push_notice_msg.py 2023-03-28 20:19:49 +08:00
midoks e4e0697b4b Update push_notice_msg.py 2023-03-28 20:18:52 +08:00
midoks 11b5ac658b Update mw.tpl 2023-03-28 18:00:50 +08:00
midoks 1306731164 up 2023-03-28 17:47:59 +08:00
midoks bb6c933aee Update README.md 2023-03-28 17:41:50 +08:00
midoks d6a93ef1e6 Update info.json 2023-03-28 17:18:59 +08:00
midoks 6610da402a Update info.json 2023-03-28 17:18:47 +08:00
midoks 3ace9cf51e Update install.sh 2023-03-28 16:54:21 +08:00
midoks 49c7ec6073 Update tgbot.py 2023-03-28 16:31:46 +08:00
midoks 8cf526667e up 2023-03-25 22:05:19 +08:00
midoks 6c42876411 Update receive_faq.py 2023-03-25 21:58:08 +08:00
midoks 79471e3806 Update receive_faq.py 2023-03-25 21:56:50 +08:00
midoks cad06425fc Update lib.sh 2023-03-23 15:24:49 +08:00
midoks 6f1e11e474 Update lib.sh 2023-03-23 15:21:22 +08:00
midoks 59d13e50ce Update rhel.sh 2023-03-22 22:26:32 +08:00
midoks 5da0746240 Update push_bbs_ntid.py 2023-03-22 18:00:32 +08:00
midoks 192ea8b029 Update push_bbs_ntid.py 2023-03-22 17:34:18 +08:00
midoks bfc20b3e42 Update push_tmp_msg.py 2023-03-22 17:01:50 +08:00
midoks 56bee5c752 Update push_tmp_msg.py 2023-03-22 16:41:26 +08:00
midoks 312df5de1f Create push_bbs_ntid.py 2023-03-22 16:41:23 +08:00
midoks 4d3640286c Update README.md 2023-03-20 17:49:48 +08:00
midoks 20930806b6 Update install.sh 2023-03-20 12:19:35 +08:00
midoks 71360b61da Update install.sh 2023-03-20 12:04:54 +08:00
midoks 411645c9e2 Update install.sh 2023-03-20 12:01:46 +08:00
midoks 3de4e1bfff up 2023-03-19 00:21:36 +08:00
midoks 34285f6051 Update push_tmp_msg.py 2023-03-19 00:20:23 +08:00
midoks 84f0cda89b up 2023-03-18 18:32:30 +08:00
midoks 04012085ce Update mdw.jpg 2023-03-17 19:18:27 +08:00
Mr Chen 265e17beac Merge pull request #393 from midoks/dev
0.13.3
2023-03-16 13:00:56 +08:00
Mr Chen 8849001384 Merge pull request #392 from midoks/dev
升级图表echarts
2023-03-09 02:49:57 +08:00
Mr Chen d6c6ae5561 Merge pull request #391 from midoks/dev
0.13.2
2023-03-09 01:49:10 +08:00
Mr Chen 704b256408 Merge pull request #390 from midoks/dev
网站统计优化
2023-03-05 18:36:57 +08:00
Mr Chen d38e9f7ad0 Merge pull request #389 from midoks/dev
OP防火墙优化
2023-03-05 18:07:54 +08:00
Mr Chen 04e43e051e Merge pull request #388 from midoks/dev
局部优化
2023-03-02 16:57:17 +08:00
Mr Chen 9d9b39dfe2 Merge pull request #387 from midoks/dev
0.13.1
2023-02-28 19:11:06 +08:00
Mr Chen 196fbbdd7d Merge pull request #382 from midoks/dev
0.13.0
2023-02-24 05:59:59 +08:00
Mr Chen 22d94ce67c Merge pull request #371 from midoks/dev
安装脚本优化3
2023-02-14 22:24:04 +08:00
Mr Chen fc5970c65d Merge pull request #370 from midoks/dev
安装脚本优化2
2023-02-14 22:09:05 +08:00
Mr Chen ea03bb056a Merge pull request #369 from midoks/dev
安装脚本优化
2023-02-14 21:59:22 +08:00
Mr Chen 628175a8ee Merge pull request #368 from midoks/dev
0.12.3
2023-02-14 20:13:04 +08:00
175 changed files with 14050 additions and 1077 deletions
+16
View File
@@ -0,0 +1,16 @@
name: sync2gitee
on: [push]
jobs:
repo-sync:
runs-on: ubuntu-latest
steps:
- name: Mirror the Github organization repos to Gitee.
uses: Yikun/hub-mirror-action@master
with:
src: 'github/midoks'
dst: 'gitee/midoks'
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
dst_token: ${{ secrets.GITEE_TOKEN }}
static_list: "mdserver-web"
force_update: true
+2 -3
View File
@@ -161,11 +161,8 @@ plugins/own_*
plugins/my_*
plugins/l2tp
plugins/openlitespeed
plugins/system_safe
plugins/tamper_proof
plugins/tamper_proof_*
plugins/cryptocurrency_trade
plugins/op_load_balance
plugins/gdrive
plugins/mtproxy
plugins/zimg
@@ -180,3 +177,5 @@ debug.out
mdioks.session-journal
*.session
+24 -19
View File
@@ -79,7 +79,7 @@ PHP[72-82]支持phpMyAdmin[5.2.0]
# 特别赞助
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan.la/)
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan.pw/)
# AD - VPS推荐 - 🙏
@@ -88,6 +88,7 @@ PHP[72-82]支持phpMyAdmin[5.2.0]
| 服务商 | LOGO | 推广地址 | 优惠码 |
| ------------- |----------|-----------|-------|
| digitalvirt |[![digitalvirt](https://digitalvirt.com/templates/BlueWhite/img/logo-dark.svg)](https://digitalvirt.com/aff.php?aff=154) | https://digitalvirt.com/aff.php?aff=154 | mdserver-web |
| mvirtua |[![mvirtua](https://mvirtua.com/upload/logo-black.png)](https://mvirtua.com/aff/FUSKXVDH) | https://mvirtua.com/aff/FUSKXVDH | mdserver-web (全场8折)|
# Docker
@@ -99,30 +100,34 @@ docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:
```
### 版本更新 0.13.3
### 版本更新 0.15.2
* tgbot插件[增加扩展功能]。
* 面板设置ssl功能优化。
* 网站统计-计划任务归档优化。
* OpenResty升级到1.21.4.2
* 计划任务自动脚本运行时间
* rsyncd添加优化
* 使用mariadb二进制导入备份文件
* docker插件-镜像导入导出功能
* 网站设置反向代理升级功能
* 优化初始化安装SSH端口识别
### JSDelivr安装地址
- 初始安装
```
curl -fsSL https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/install.sh | bash
curl --insecure -fsSL https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/install.sh | bash
```
- 直接更新
```
curl -fsSL https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/update.sh | bash
curl --insecure -fsSL https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/update.sh | bash
```
- 卸载脚本
```
wget -O uninstall.sh https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/uninstall.sh && bash uninstall.sh
wget --no-check-certificate -O uninstall.sh https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/uninstall.sh && bash uninstall.sh
```
### 备用地址
@@ -130,20 +135,20 @@ wget -O uninstall.sh https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scri
- 初始安装
```
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/install.sh | bash
curl --insecure -fsSL https://gitee.com/midoks/mdserver-web/raw/master/scripts/install.sh | bash
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/install.sh | bash
curl --insecure -fsSL https://code.midoks.me/midoks/mdserver-web/raw/branch/master/scripts/install.sh | bash
```
- 直接更新
```
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/update.sh | bash
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/update.sh | bash
```
- 卸载脚本
```
wget -O uninstall.sh https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/uninstall.sh && bash uninstall.sh
wget --no-check-certificate -O uninstall.sh https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/uninstall.sh && bash uninstall.sh
```
@@ -152,22 +157,22 @@ wget -O uninstall.sh https://raw.githubusercontent.com/midoks/mdserver-web/maste
- 需已经安装mdserver-web
```
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/quick/app.sh | bash
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/quick/app.sh | bash
```
### DEV使用
```
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install_dev.sh | bash
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/update_dev.sh | bash
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install_dev.sh | bash
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/update_dev.sh | bash
wget -O uninstall.sh https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/uninstall.sh && bash uninstall.sh
wget --no-check-certificate -O uninstall.sh https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/uninstall.sh && bash uninstall.sh
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/quick/debug.sh | bash
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/quick/debug.sh | bash
curl -fsSL https://gitee.com/midoks/mdserver-web/raw/dev/scripts/install_dev.sh | bash
curl -fsSL https://gitee.com/midoks/mdserver-web/raw/dev/scripts/update_dev.sh | bash
curl --insecure -fsSL https://code.midoks.me/midoks/mdserver-web/raw/branch/dev/scripts/install_dev.sh | bash
curl --insecure -fsSL https://code.midoks.me/midoks/mdserver-web/raw/branch/dev/scripts/update_dev.sh | bash
```
### 捐赠地址 USDT(TRC20)
+1
View File
@@ -28,6 +28,7 @@ from route import app, socketio
from gevent.pywsgi import WSGIServer
from geventwebsocket.handler import WebSocketHandler
from gevent import monkey
monkey.patch_all()
+8 -7
View File
@@ -930,7 +930,8 @@ fi
index).encode()
)
X509Req.set_pubkey(pk)
X509Req.set_version(2)
# X509Req.set_version(2)
X509Req.set_version(0)
X509Req.sign(pk, self.__digest)
return OpenSSL.crypto.dump_certificate_request(OpenSSL.crypto.FILETYPE_ASN1, X509Req)
@@ -1006,7 +1007,7 @@ fi
try:
result = {}
x509 = OpenSSL.crypto.load_certificate(
OpenSSL.crypto.FILETYPE_PEM, public.readFile(pem_file))
OpenSSL.crypto.FILETYPE_PEM, mw.readFile(pem_file))
# 取产品名称
issuer = x509.get_issuer()
result['issuer'] = ''
@@ -1280,16 +1281,16 @@ fullchain.pem 粘贴到证书输入框
# 获取当前正在使用此证书的网站目录
def getSslUsedSite(self, save_path):
pkey_file = '{}/privkey.pem'.format(save_path)
pkey = public.readFile(pkey_file)
pkey = mw.readFile(pkey_file)
if not pkey:
return False
cert_paths = 'vhost/cert'
import panelSite
args = public.dict_obj()
args = mw.dict_obj()
args.siteName = ''
for c_name in os.listdir(cert_paths):
skey_file = '{}/{}/privkey.pem'.format(cert_paths, c_name)
skey = public.readFile(skey_file)
skey = mw.readFile(skey_file)
if not skey:
continue
if skey == pkey:
@@ -1297,7 +1298,7 @@ fullchain.pem 粘贴到证书输入框
run_path = panelSite.panelSite().GetRunPath(args)
if not run_path:
continue
sitePath = public.M('sites').where(
sitePath = mw.M('sites').where(
'name=?', c_name).getField('path')
if not sitePath:
continue
@@ -1315,7 +1316,7 @@ fullchain.pem 粘贴到证书输入框
self.__config['orders'] = {}
import panelSite
siteObj = panelSite.panelSite()
args = public.dict_obj()
args = mw.dict_obj()
for siteName in os.listdir(cert_path):
try:
cert_file = '{}/{}/fullchain.pem'.format(cert_path, siteName)
+8 -7
View File
@@ -840,7 +840,8 @@ class cert_request:
index).encode()
)
X509Req.set_pubkey(pk)
X509Req.set_version(2)
# X509Req.set_version(2)
X509Req.set_version(0)
X509Req.sign(pk, self.__digest)
return OpenSSL.crypto.dump_certificate_request(OpenSSL.crypto.FILETYPE_ASN1, X509Req)
@@ -916,7 +917,7 @@ class cert_request:
try:
result = {}
x509 = OpenSSL.crypto.load_certificate(
OpenSSL.crypto.FILETYPE_PEM, public.readFile(pem_file))
OpenSSL.crypto.FILETYPE_PEM, mw.readFile(pem_file))
# 取产品名称
issuer = x509.get_issuer()
result['issuer'] = ''
@@ -1186,16 +1187,16 @@ fullchain.pem 粘贴到证书输入框
# 获取当前正在使用此证书的网站目录
def getSslUsedSite(self, save_path):
pkey_file = '{}/privkey.pem'.format(save_path)
pkey = public.readFile(pkey_file)
pkey = mw.readFile(pkey_file)
if not pkey:
return False
cert_paths = 'vhost/cert'
import panelSite
args = public.dict_obj()
args = mw.dict_obj()
args.siteName = ''
for c_name in os.listdir(cert_paths):
skey_file = '{}/{}/privkey.pem'.format(cert_paths, c_name)
skey = public.readFile(skey_file)
skey = mw.readFile(skey_file)
if not skey:
continue
if skey == pkey:
@@ -1203,7 +1204,7 @@ fullchain.pem 粘贴到证书输入框
run_path = panelSite.panelSite().GetRunPath(args)
if not run_path:
continue
sitePath = public.M('sites').where(
sitePath = mw.M('sites').where(
'name=?', c_name).getField('path')
if not sitePath:
continue
@@ -1221,7 +1222,7 @@ fullchain.pem 粘贴到证书输入框
self.__config['orders'] = {}
import panelSite
siteObj = panelSite.panelSite()
args = public.dict_obj()
args = mw.dict_obj()
for siteName in os.listdir(cert_path):
try:
cert_file = '{}/{}/fullchain.pem'.format(cert_path, siteName)
+12
View File
@@ -33,6 +33,7 @@ from flask import redirect
def init():
initDB()
initDBSshPort()
initUserInfo()
initInitD()
initInitTask()
@@ -62,6 +63,17 @@ def initDB():
print(str(ex))
def initDBSshPort():
# SSH端口必须放开
import firewall_api
cmd_data = mw.execShell(
"cat /etc/ssh/sshd_config | grep '^Port \d*' | tail -1")
ssh_port = cmd_data[0].replace("Port ", '').strip()
if ssh_port == '':
ssh_port = '22'
firewall_api.firewall_api().addAcceptPortArgs(ssh_port, 'SSH远程管理服务', 'port')
def doContentReplace(src, dst):
content = mw.readFile(src)
content = content.replace("{$SERVER_PATH}", mw.getRunDir())
+8 -1
View File
@@ -27,7 +27,7 @@ from flask import request
class config_api:
__version = '0.13.3'
__version = '0.15.2'
__api_addr = 'data/api.json'
def __init__(self):
@@ -788,6 +788,13 @@ class config_api:
return mw.returnData(True, '验证成功')
return mw.returnData(False, '验证失败')
if tag == 'email':
t = json.loads(tag_data)
test_bool = mw.emailNotifyTest(t)
if test_bool:
return mw.returnData(True, '验证成功')
return mw.returnData(False, '验证失败')
return mw.returnData(False, '暂时未支持该验证')
def setNotifyEnableApi(self):
+21 -2
View File
@@ -508,6 +508,22 @@ class crontab_api:
else:
head = "#!/bin/bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n"
start_head = '''
SCRIPT_RUN_TIME="0s"
MW_ToSeconds()
{
SEC=$1
if [ $SEC -lt 60 ]; then
SCRIPT_RUN_TIME="${SEC}s"
elif [ $SEC -ge 60 ] && [ $SEC -lt 3600 ];then
SCRIPT_RUN_TIME="$(( SEC / 60 ))m$(( SEC % 60 ))s"
elif [ $SEC -ge 3600 ]; then
SCRIPT_RUN_TIME="$(( SEC / 3600 ))h$(( (SEC % 3600) / 60 ))m$(( (SEC % 3600) % 60 ))s"
fi
}
START_MW_SHELL_TIME=`date +%s`
'''
source_bin_activate = '''
export LANG=en_US.UTF-8
MW_PATH=%s/bin/activate
@@ -515,7 +531,7 @@ if [ -f $MW_PATH ];then
source $MW_PATH
fi''' % (mw.getRunDir(),)
head = head + source_bin_activate + "\n"
head = head + start_head + source_bin_activate + "\n"
log = '.log'
script_dir = mw.getRunDir() + "/scripts"
@@ -557,7 +573,10 @@ fi''' % (mw.getRunDir(),)
shell += '''
echo "----------------------------------------------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "★[$endDate] Successful"
END_MW_SHELL_TIME=`date +"%s"`
((SHELL_COS_TIME=($END_MW_SHELL_TIME-$START_MW_SHELL_TIME)))
MW_ToSeconds $SHELL_COS_TIME
echo "★[$endDate] Successful | Script Run [$SCRIPT_RUN_TIME] "
echo "----------------------------------------------------------------------------"
'''
cronPath = mw.getServerDir() + '/cron'
+1 -1
View File
@@ -65,7 +65,7 @@ class Sql():
self.__DB_TABLE = table
return self
def where(self, where, param):
def where(self, where, param=()):
# WHERE条件
if where:
self.__OPT_WHERE = " WHERE " + where
+174 -4
View File
@@ -23,11 +23,13 @@ import shlex
import datetime
import subprocess
import glob
import base64
import re
import db
from random import Random
import db
def execShell(cmdstring, cwd=None, timeout=None, shell=True):
@@ -776,6 +778,133 @@ def deDoubleCrypt(key, strings):
return strings
def aesEncrypt(data, key='ABCDEFGHIJKLMNOP', vi='0102030405060708'):
# aes加密
# @param data 被加密的数据
# @param key 加解密密匙 16位
# @param vi 16位
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
if not isinstance(data, bytes):
data = data.encode()
# AES_CBC_KEY = os.urandom(32)
# AES_CBC_IV = os.urandom(16)
AES_CBC_KEY = key.encode()
AES_CBC_IV = vi.encode()
# print("AES_CBC_KEY:", AES_CBC_KEY)
# print("AES_CBC_IV:", AES_CBC_IV)
padder = padding.PKCS7(algorithms.AES.block_size).padder()
padded_data = padder.update(data) + padder.finalize()
cipher = Cipher(algorithms.AES(AES_CBC_KEY),
modes.CBC(AES_CBC_IV),
backend=default_backend())
encryptor = cipher.encryptor()
edata = encryptor.update(padded_data)
# print(edata)
# print(str(edata))
# print(edata.decode())
return edata
def aesDecrypt(data, key='ABCDEFGHIJKLMNOP', vi='0102030405060708'):
# aes加密
# @param data 被解密的数据
# @param key 加解密密匙 16位
# @param vi 16位
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
if not isinstance(data, bytes):
data = data.encode()
AES_CBC_KEY = key.encode()
AES_CBC_IV = vi.encode()
cipher = Cipher(algorithms.AES(AES_CBC_KEY),
modes.CBC(AES_CBC_IV),
backend=default_backend())
decryptor = cipher.decryptor()
ddata = decryptor.update(data)
unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
data = unpadder.update(ddata)
try:
uppadded_data = data + unpadder.finalize()
except ValueError:
raise Exception('无效的加密信息!')
return uppadded_data
def aesEncrypt_Crypto(data, key, vi):
# 该方法保留,暂时不使用
# aes加密
# @param data 被加密的数据
# @param key 加解密密匙 16位
# @param vi 16位
from Crypto.Cipher import AES
cryptor = AES.new(key.encode('utf8'), AES.MODE_CBC, vi.encode('utf8'))
# 判断是否含有中文
zhmodel = re.compile(u'[\u4e00-\u9fff]')
match = zhmodel.search(data)
if match == None:
# 无中文时
add = 16 - len(data) % 16
pad = lambda s: s + add * chr(add)
data = pad(data)
enctext = cryptor.encrypt(data.encode('utf8'))
else:
# 含有中文时
data = data.encode()
add = 16 - len(data) % 16
data = data + add * (chr(add)).encode()
enctext = cryptor.encrypt(data)
encodestrs = base64.b64encode(enctext).decode('utf8')
return encodestrs
def aesDecrypt_Crypto(data, key, vi):
# 该方法保留,暂时不使用
# aes加密
# @param data 被加密的数据
# @param key 加解密密匙 16位
# @param vi 16位
from crypto.Cipher import AES
data = data.encode('utf8')
encodebytes = base64.urlsafe_b64decode(data)
cipher = AES.new(key.encode('utf8'), AES.MODE_CBC, vi.encode('utf8'))
text_decrypted = cipher.decrypt(encodebytes)
# 判断是否含有中文
zhmodel = re.compile(u'[\u4e00-\u9fff]')
match = zhmodel.search(text_decrypted)
if match == False:
# 无中文时补位
unpad = lambda s: s[0:-s[-1]]
text_decrypted = unpad(text_decrypted)
text_decrypted = text_decrypted.decode('utf8').rstrip() # 去掉补位的右侧空格
return text_decrypted
def buildSoftLink(src, dst, force=False):
'''
建立软连接
@@ -1086,6 +1215,12 @@ def formatDate(format="%Y-%m-%d %H:%M:%S", times=None):
return time.strftime(format, time_local)
def strfToTime(sdate):
# 转换时间
import time
return time.strftime('%Y-%m-%d', time.strptime(sdate, '%b %d %H:%M:%S %Y %Z'))
def checkIp(ip):
# 检查是否为IPv4地址
import re
@@ -1276,7 +1411,7 @@ def makeConf():
file = getRunDir() + '/data/json/config.json'
if not os.path.exists(file):
c = {}
c['title'] = '金蝉面板'
c['title'] = '金灵面板'
c['home'] = 'http://github/midoks/mdserver-web'
c['recycle_bin'] = True
c['template'] = 'default'
@@ -1697,7 +1832,7 @@ def getNotifyData(is_parse=False):
data = json.loads(notify_data)
if is_parse:
tag_list = ['tgbot']
tag_list = ['tgbot', 'email']
for t in tag_list:
if t in data and 'cfg' in data[t]:
data[t]['data'] = json.loads(deDoubleCrypt(t, data[t]['cfg']))
@@ -1759,6 +1894,34 @@ def tgbotNotifyTest(app_token, chat_id):
return tgbotNotifyHttpPost(app_token, chat_id, msg)
def emailNotifyMessage(data):
'''
邮件通知
'''
sys.path.append(os.getcwd() + "/class/plugin")
import memail
try:
if data['smtp_ssl'] == 'ssl':
memail.sendSSL(data['smtp_host'], data['smtp_port'],
data['username'], data['password'],
data['to_mail_addr'], data['subject'], data['content'])
else:
memail.send(data['smtp_host'], data['smtp_port'],
data['username'], data['password'],
data['to_mail_addr'], data['subject'], data['content'])
return True
except Exception as e:
print(getTracebackInfo())
return False
def emailNotifyTest(data):
# print(data)
data['subject'] = 'MW通知测试'
data['content'] = data['mail_test']
return emailNotifyMessage(data)
def notifyMessageTry(msg, stype='common', trigger_time=300, is_write_log=True):
lock_file = getPanelTmp() + '/notify_lock.json'
@@ -1796,6 +1959,13 @@ def notifyMessageTry(msg, stype='common', trigger_time=300, is_write_log=True):
else:
do_notify = tgbotNotifyMessage(
t['app_token'], t['chat_id'], msg)
if 'email' in data and 'enable' in data['email']:
if data['email']['enable']:
t = data['email']['data']
t['subject'] = 'MW通知'
t['content'] = msg
do_notify = emailNotifyMessage(t)
return do_notify
+27 -10
View File
@@ -71,8 +71,9 @@ class plugins_api:
if not mw.isNumber(sType):
sType = 0
# print sPage
data = self.getPluginList(sType, int(sPage))
# print(sPage, sType)
search = request.args.get('search', '').lower()
data = self.getPluginList(sType, search, int(sPage))
return mw.getJson(data)
def menuGetAbsPath(self, tag, path):
@@ -138,7 +139,7 @@ class plugins_api:
def initApi(self):
plugin_names = {
'openresty': '1.21.4.1',
'openresty': '1.21.4.2',
'php': '56',
'swap': '1.1',
'mysql': '5.7',
@@ -781,7 +782,18 @@ class plugins_api:
print(e)
return plugins_info
def getAllListPage(self, sType='0', page=1, pageSize=10):
def searchKey(self, info, kw):
try:
if info['title'].lower().find(kw) > -1:
return True
if info['ps'].lower().find(kw) > -1:
return True
if info['name'].lower().find(kw) > -1:
return True
except Exception as e:
return False
def getAllListPage(self, sType='0', kw='', page=1, pageSize=10):
plugins_info = []
for dirinfo in os.listdir(self.__plugin_dir):
if dirinfo[0:1] == '.':
@@ -792,11 +804,13 @@ class plugins_api:
if os.path.exists(json_file):
try:
data = json.loads(mw.readFile(json_file))
# 判断是否搜索
if kw != '' and not self.searchKey(data, kw):
continue
tmp_data = self.makeList(data, sType)
for index in range(len(tmp_data)):
plugins_info.append(tmp_data[index])
except Exception as e:
print(json_file)
print(mw.getTracebackInfo())
start = (page - 1) * pageSize
@@ -927,14 +941,14 @@ class plugins_api:
return plugins_info
def getPluginList(self, sType, sPage=1, sPageSize=10):
# print sType, sPage, sPageSize
def getPluginList(self, sType, kw='', sPage=1, sPageSize=10):
# print(sType, kw, sPage, sPageSize)
ret = {}
ret['type'] = json.loads(mw.readFile(self.__type))
# plugins_info = self.getAllListThread(sType)
# plugins_info = self.getAllListProcess(sType)
data = self.getAllListPage(sType, sPage, sPageSize)
data = self.getAllListPage(sType, kw, sPage, sPageSize)
ret['data'] = data[0]
args = {}
@@ -1016,8 +1030,11 @@ class plugins_api:
# shell 调用
def run(self, name, func, version='', args='', script='index'):
path = self.__plugin_dir + \
'/' + name + '/' + script + '.py'
path = self.__plugin_dir + '/' + name + '/' + script + '.py'
if not os.path.exists(path):
path = self.__plugin_dir + '/' + name + '/' + name + '.py'
py = 'python3 ' + path
if args == '':
+125 -56
View File
@@ -101,19 +101,31 @@ class site_api:
limit = request.form.get('limit', '10')
p = request.form.get('p', '1')
type_id = request.form.get('type_id', '0').strip()
search = request.form.get('search', '').strip()
start = (int(p) - 1) * (int(limit))
siteM = mw.M('sites').field('id,name,path,status,ps,addtime,edate')
if type_id != '' and int(type_id) >= 0:
siteM.where('type_id=?', (type_id,))
sql_where = ''
if search != '':
sql_where = " name like '%" + search + "%' or ps like '%" + search + "%' "
if type_id != '' and int(type_id) >= 0 and search != '':
sql_where = sql_where + " and type_id=" + type_id + ""
elif type_id != '' and int(type_id) >= 0:
sql_where = " type_id=" + type_id
if sql_where != '':
siteM.where(sql_where)
_list = siteM.limit((str(start)) + ',' +
limit).order('id desc').select()
for i in range(len(_list)):
_list[i]['backup_count'] = mw.M('backup').where(
"pid=? AND type=?", (_list[i]['id'], 0)).count()
if _list != None:
for i in range(len(_list)):
_list[i]['backup_count'] = mw.M('backup').where(
"pid=? AND type=?", (_list[i]['id'], 0)).count()
_ret = {}
_ret['data'] = _list
@@ -775,6 +787,9 @@ class site_api:
mw.execShell('echo "lets" > "' + path + '/README"')
elif ssl_type == 'acme':
ssl_acme_dir = mw.getAcmeDir() + '/' + site_name
if not os.path.exists(ssl_acme_dir):
ssl_acme_dir = mw.getAcmeDir() + '/' + site_name + '_ecc'
acme_csrpath = ssl_acme_dir + '/fullchain.cer'
acme_keypath = ssl_acme_dir + '/' + site_name + '.key'
if mw.md5(mw.readFile(acme_csrpath)) == mw.md5(mw.readFile(csr_path)):
@@ -1420,6 +1435,8 @@ class site_api:
data['data'] = mw.readFile(filename)
data['rlist'] = []
for ds in os.listdir(self.rewritePath):
if ds[0:1] == '.':
continue
if ds == 'list.txt':
continue
data['rlist'].append(ds[0:len(ds) - 5])
@@ -1853,19 +1870,16 @@ class site_api:
if _id == '' or _siteName == '':
return mw.returnJson(False, "必填项不能为空!")
_old_config = mw.readFile(
"{}/{}/{}.conf".format(self.proxyPath, _siteName, _id))
if _old_config == False:
return mw.returnJson(False, "非法操作")
mw.writeFile("{}/{}/{}.conf".format(self.proxyPath,
_siteName, _id), _config)
proxy_file = "{}/{}/{}.conf".format(self.proxyPath, _siteName, _id)
mw.backFile(proxy_file)
mw.writeFile(proxy_file, _config)
rule_test = mw.checkWebConfig()
if rule_test != True:
mw.writeFile("{}/{}/{}.conf".format(self.proxyPath,
_siteName, _id), _old_config)
mw.restoreFile(proxy_file)
mw.removeBackFile(proxy_file)
return mw.returnJson(False, "OpenResty 配置测试不通过, 请重试: {}".format(rule_test))
mw.removeBackFile(proxy_file)
self.operateRedirectConf(_siteName, 'start')
mw.restartWeb()
return mw.returnJson(True, "ok")
@@ -1906,21 +1920,20 @@ class site_api:
_from = request.form.get('from', '')
_to = request.form.get('to', '')
_host = request.form.get('host', '')
_name = request.form.get('name', '')
_open_proxy = request.form.get('open_proxy', '')
_open_cache = request.form.get('open_cache', '')
_cache_time = request.form.get('cache_time', '')
_id = request.form.get('id', '')
if _siteName == "" or _from == "" or _to == "" or _host == "":
# print(_name, _siteName, _from, _to, _host)
if _name == "" or _siteName == "" or _from == "" or _to == "" or _host == "":
return mw.returnJson(False, "必填项不能为空")
data_path = self.getProxyDataPath(_siteName)
data_content = mw.readFile(
data_path) if os.path.exists(data_path) else ""
data = json.loads(data_content) if data_content != "" else []
rep = "http(s)?\:\/\/([a-zA-Z0-9][-a-zA-Z0-9]{0,62}\.)+([a-zA-Z0-9][a-zA-Z0-9]{0,62})+.?"
if not re.match(rep, _to):
return mw.returnJson(False, "错误的目标地址!")
# _to = _to.strip("/")
# get host from url
try:
if _host == "$host":
@@ -1929,7 +1942,11 @@ class site_api:
except:
return mw.returnJson(False, "错误的目标地址")
# location ~* ^{from}(.*)$ {
proxy_site_path = self.getProxyDataPath(_siteName)
data_content = mw.readFile(
proxy_site_path) if os.path.exists(proxy_site_path) else ""
data = json.loads(data_content) if data_content != "" else []
tpl = "#PROXY-START\n\
location ^~ {from} {\n\
proxy_pass {to};\n\
@@ -1937,12 +1954,29 @@ location ^~ {from} {\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\
proxy_set_header Upgrade $http_upgrade;\n\
proxy_set_header Connection $connection_upgrade;\n\
proxy_http_version 1.1;\n\
\n\
add_header X-Cache $upstream_cache_status;\n\
proxy_ignore_headers Set-Cookie Cache-Control expires;\n\
add_header Cache-Control no-cache;\n\
\n\
set $static_files_app 0;\n\
{proxy_cache}\n\
}\n\
# PROXY-END"
tpl_proxy_cache = "\n\
if ( $uri ~* \"\.(gif|png|jpg|css|js|woff|woff2)$\" )\n\
{\n\
expires {cache_time}m;\n\
}\n\
proxy_ignore_headers Set-Cookie Cache-Control expires;\n\
proxy_cache mw_cache;\n\
proxy_cache_key \"$host$uri$is_args$args\";\n\
proxy_cache_valid 200 304 301 302 {cache_time}m;\n\
"
tpl_proxy_nocache = "\n\
set $static_files_app 0; \n\
if ( $uri ~* \"\.(gif|png|jpg|css|js|woff|woff2)$\" )\n\
{\n\
set $static_files_app 1;\n\
@@ -1952,8 +1986,7 @@ location ^~ {from} {\n\
{\n\
add_header Cache-Control no-cache;\n\
}\n\
}\n\
#PROXY-END"
"
# replace
if _from[0] != '/':
@@ -1961,28 +1994,69 @@ location ^~ {from} {\n\
tpl = tpl.replace("{from}", _from, 999)
tpl = tpl.replace("{to}", _to)
tpl = tpl.replace("{host}", _host, 999)
tpl = tpl.replace("{cache_time}", _cache_time, 999)
_id = mw.md5("{}+{}+{}".format(_from, _to, _siteName))
for item in data:
if item["id"] == _id:
return mw.returnJson(False, "已存在该规则!")
if item["from"] == _from:
return mw.returnJson(False, "代理目录已存在!")
data.append({
"from": _from,
"to": _to,
"host": _host,
"id": _id
})
if _open_cache == 'on':
tpl_proxy_cache = tpl_proxy_cache.replace(
"{cache_time}", _cache_time, 999)
tpl = tpl.replace("{proxy_cache}", tpl_proxy_cache, 999)
else:
tpl = tpl.replace("{proxy_cache}", tpl_proxy_nocache, 999)
proxy_action = 'add'
if _id == "":
_id = mw.md5("{}".format(_name))
else:
proxy_action = 'edit'
conf_proxy = "{}/{}.conf".format(self.getProxyPath(_siteName), _id)
conf_bk = "{}/{}.conf.txt".format(self.getProxyPath(_siteName), _id)
mw.writeFile(conf_proxy, tpl)
rule_test = mw.checkWebConfig()
if rule_test != True:
os.remove(conf_proxy)
return mw.returnJson(False, "OpenResty配置测试不通过, 请重试: {}".format(rule_test))
if proxy_action == "add":
# 添加代理
_id = mw.md5("{}".format(_name))
for item in data:
if item["name"] == _name:
return mw.returnJson(False, "名称重复!")
if item["from"] == _from:
return mw.returnJson(False, "代理目录已存在!")
data.append({
"name": _name,
"from": _from,
"to": _to,
"host": _host,
"open_cache": _open_cache,
"open_proxy": _open_proxy,
"cache_time": _cache_time,
"id": _id,
})
else:
# 修改代理
dindex = -1
for x in range(len(data)):
if data[x]["id"] == _id:
dindex = x
break
if dindex < 0:
return mw.returnJson(False, "异常请求")
data[dindex]['from'] = _from
data[dindex]['to'] = _to
data[dindex]['host'] = _host
data[dindex]['open_cache'] = _open_cache
data[dindex]['open_proxy'] = _open_proxy
data[dindex]['cache_time'] = _cache_time
conf_file = "{}/{}.conf".format(self.getProxyPath(_siteName), _id)
if _open_proxy != 'on':
conf_file = "{}/{}.conf.txt".format(
self.getProxyPath(_siteName), _id)
mw.writeFile(data_path, json.dumps(data))
mw.writeFile(conf_file, tpl)
os.rename(conf_proxy, conf_bk)
mw.writeFile(proxy_site_path, json.dumps(data))
self.operateProxyConf(_siteName, 'start')
mw.restartWeb()
return mw.returnJson(True, "ok", {"hash": _id})
@@ -2013,10 +2087,10 @@ location ^~ {from} {\n\
self.getProxyPath(_siteName), _id)
mw.execShell(cmd)
except:
return mw.returnJson(False, "删除失败!")
return mw.returnJson(False, "删除反代失败!")
mw.restartWeb()
return mw.returnJson(True, "删除成功!")
return mw.returnJson(True, "删除反代成功!")
def getSiteTypesApi(self):
# 取网站分类
@@ -2083,7 +2157,7 @@ location ^~ {from} {\n\
##### ----- end ----- ###
# 域名编码转换
# 域名编码转换
def toPunycode(self, domain):
import re
if sys.version_info[0] == 2:
@@ -2091,7 +2165,7 @@ location ^~ {from} {\n\
tmp = domain.split('.')
newdomain = ''
for dkey in tmp:
# 匹配非ascii字符
# 匹配非ascii字符
match = re.search(u"[\x80-\xff]+", dkey)
if not match:
newdomain += dkey + '.'
@@ -2646,7 +2720,7 @@ location ^~ {from} {\n\
mw.writeLog('TYPE_SITE', '设置成功,站点到期后将自动停止!', (siteName, edate))
return mw.returnJson(True, '设置成功,站点到期后将自动停止!')
# ssl相关方法 start
# ssl相关方法 start
def setSslConf(self, siteName):
file = self.getHostConf(siteName)
conf = mw.readFile(file)
@@ -2745,9 +2819,4 @@ location ^~ {from} {\n\
mw.execShell("chattr +i " + filename)
return mw.returnJson(True, '已打开防跨站设置!')
# 转换时间
def strfToTime(self, sdate):
import time
return time.strftime('%Y-%m-%d', time.strptime(sdate, '%b %d %H:%M:%S %Y %Z'))
# ssl相关方法 end
# ssl相关方法 end
+10
View File
@@ -755,6 +755,8 @@ class system_api:
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
P_VER=`python3 -V | awk '{print $2}'`
if [ ! -f /www/server/mdserver-web/bin/activate ];then
cd /www/server/mdserver-web && python3 -m venv .
cd /www/server/mdserver-web && source /www/server/mdserver-web/bin/activate
@@ -769,6 +771,14 @@ if [ ! -z "$cn" ];then
fi
cd /www/server/mdserver-web && pip3 install -r /www/server/mdserver-web/requirements.txt -i $PIPSRC
P_VER_D=`echo "$P_VER"|awk -F '.' '{print $1}'`
P_VER_M=`echo "$P_VER"|awk -F '.' '{print $2}'`
NEW_P_VER=${P_VER_D}.${P_VER_M}
if [ -f /www/server/mdserver-web/version/r${NEW_P_VER}.txt ];then
cd /www/server/mdserver-web && pip3 install -r /www/server/mdserver-web/version/r${NEW_P_VER}.txt -i $PIPSRC
fi
'''
os.system(update_env)
self.restartMw()
+48
View File
@@ -0,0 +1,48 @@
# coding:utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# VIP用户管理
# ---------------------------------------------------------------------------------
import mw
from flask import request
import requests
class vip_api:
api_url = 'https://wo.midoks.me/api/wp-json/vip'
def __init__(self):
pass
def loginApi(self):
username = request.form.get('username', '')
password = request.form.get('password', '')
password = mw.aesEncrypt(password)
headers = {
"Content-Type": "application/x-www-form-urlencoded",
}
print("name:", str(username))
print("pwd:", str(password))
args = {
'name': username,
'pass': password
}
data = requests.post(self.api_url + '/v1/login',
data=args, headers=headers)
print(data.text)
return mw.returnJson(False, "测试中!")
+43
View File
@@ -0,0 +1,43 @@
# coding: utf-8
import smtplib
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
def send(smtp_host, smtp_port, username, password, to_mail, subject, content):
smtp = smtplib.SMTP()
smtp.connect(smtp_host, port=smtp_port)
smtp.login(user=username, password=password)
msg = MIMEText(content, 'plain', 'utf-8')
msg['From'] = _format_addr(username)
msg['To'] = _format_addr(to_mail)
msg['Subject'] = Header(subject, 'utf-8').encode()
smtp.sendmail(from_addr=username, to_addrs=to_mail, msg=msg.as_string())
return True
def sendSSL(smtp_host, smtp_port, username, password, to_mail, subject, content):
smtp = smtplib.SMTP_SSL(smtp_host, port=smtp_port)
smtp.login(user=username, password=password)
msg = MIMEText(content, 'plain', 'utf-8')
msg['From'] = _format_addr(username)
msg['To'] = _format_addr(to_mail)
msg['Subject'] = Header(subject, 'utf-8').encode()
smtp.sendmail(from_addr=username, to_addrs=to_mail, msg=msg.as_string())
smtp.quit()
return True
+2 -2
View File
@@ -16,7 +16,7 @@ mw_start_task()
{
isStart=$(ps aux |grep 'task.py'|grep -v grep|awk '{print $2}')
if [ "$isStart" == '' ];then
echo -e "Starting mw-tasks... \c"
echo -e "starting mw-tasks... \c"
cd $DIR && python3 task.py >> ${DIR}/logs/task.log 2>&1 &
sleep 0.3
isStart=$(ps aux |grep 'task.py'|grep -v grep|awk '{print $2}')
@@ -30,7 +30,7 @@ mw_start_task()
fi
echo -e "\033[32mdone\033[0m"
else
echo "Starting mw-tasks... mw-tasks (pid $(echo $isStart)) already running"
echo "starting mw-tasks... mw-tasks (pid $(echo $isStart)) already running"
fi
}
+20 -17
View File
@@ -16,6 +16,7 @@ cd /www/server/mdserver-web/plugins/php/versions && bash all_test.sh
| CentOS 9 Stream |✅ |✅ |
| Debian 10.3 |✅ |✅ |
| Debian 11.3 |✅ |✅ |
| Debian 12.0 |✅ |✅ |
| Ubuntu 18.04 |✅ |✅ |
| Ubuntu 20.04 |✅ |✅ |
| Ubuntu 22.04 |✅ |✅ |
@@ -28,23 +29,24 @@ cd /www/server/mdserver-web/plugins/php/versions && bash all_test.sh
| 系统名称 |PHP53 |PHP54 |PHP55 |PHP56 |PHP70 |PHP71 |PHP72 |PHP73 |PHP74 |PHP80 |PHP81 |
| ----------------- |-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
| CentOS 7.9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 8.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 8 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 9 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Debian 10.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Debian 11.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 18.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 20.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 22.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Fedora 31 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Fedora 32 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| AlmaLinux 9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| RockyLinux 8.6 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Arch Linux |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| openSUSE 15.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| 系统名称 |PHP53 |PHP54 |PHP55 |PHP56 |PHP70 |PHP71 |PHP72 |PHP73 |PHP74 |PHP80 |PHP81 |PHP82 |
| ----------------- |-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
| CentOS 7.9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 8.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 8 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 9 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Debian 10.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Debian 11.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Debian 12 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 18.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 20.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 22.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Fedora 31 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Fedora 32 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| AlmaLinux 9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| RockyLinux 8.6 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Arch Linux |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| openSUSE 15.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
@@ -56,6 +58,7 @@ cd /www/server/mdserver-web/plugins/php/versions && bash all_test.sh
| CentOS 9 Stream |✅ |✅ |✅ |✅ |
| Debian 10.3 |✅ |✅ |✅ |✅ |
| Debian 11.3 |✅ |✅ |✅ |✅ |
| Debian 12 |✅ |✅ |✅ |✅ |
| Ubuntu 18.04 |✅ |✅ |✅ |✅ |
| Ubuntu 20.04 |✅ |✅ |✅ |✅ |
| Ubuntu 22.04 |✅ |✅ |✅ |✅ |
+2 -3
View File
@@ -46,9 +46,8 @@ CREATE TABLE IF NOT EXISTS `firewall` (
INSERT INTO `firewall` (`id`, `port`, `ps`, `addtime`) VALUES
(1, '80', '网站默认端口', '0000-00-00 00:00:00'),
(2, '22', 'SSH远程管理服务', '0000-00-00 00:00:00'),
(3, '443', 'HTTPS', '0000-00-00 00:00:00'),
(4, '888', 'phpMyAdmin默认端口', '0000-00-00 00:00:00');
(2, '443', 'HTTPS', '0000-00-00 00:00:00'),
(3, '888', 'phpMyAdmin默认端口', '0000-00-00 00:00:00');
+2 -9
View File
@@ -39,20 +39,13 @@ server
allow all;
}
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)$
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
{
expires 30d;
error_log off;
error_log /dev/null;
access_log /dev/null;
}
location ~ .*\\.(js|css)?$
{
expires 12h;
error_log off;
access_log /dev/null;
}
access_log {$LOGPATH}/{$SERVER_NAME}.log main;
error_log {$LOGPATH}/{$SERVER_NAME}.error.log;
}
+3 -10
View File
@@ -35,18 +35,11 @@ server
allow all;
}
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)$
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
{
expires 30d;
error_log off;
error_log /dev/null;
access_log /dev/null;
}
location ~ .*\\.(js|css)?$
{
expires 12h;
error_log off;
access_log /dev/null;
expires 30d;
}
access_log {$LOGPATH}/{$SERVER_MAIN}_{$DIRBIND}.log;
+1
View File
@@ -0,0 +1 @@
存放VIP关键数据
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+58
View File
@@ -0,0 +1,58 @@
<style type="text/css">
.docker-sub {
border-bottom: 1px solid #ccc;
height: 30px;
line-height: 30px;
margin-bottom: 15px;
}
.docker-sub .on {
border-bottom: 2px solid #20a53a;
color: #20a53a;
font-weight: bold;
font-family: "宋体";
}
.docker-sub span {
display: inline-block;
font-size: 14px;
height: 30px;
padding: 0 25px;
cursor: pointer;
}
.docker-environments {
resize: none;
width: 330px;
height: 80px;
line-height: 20px;
padding: 5px 8px;
border: 1px solid #ddd;
font-size: 12px;
}
</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('docker');">服务</p>
<p onclick="pluginInitD('docker');">自启动</p>
<p onclick="dockerConList();">容器列表</p>
<p onclick="dockerImageList();">镜像列表</p>
<p onclick="dockerImageOutput();">镜像导出</p>
<p onclick="dockerIpList();">IP地址池</p>
<p onclick="repoList();">仓库</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<script type="text/javascript">
resetPluginWinWidth(800);
resetPluginWinHeight(400);
$.getScript( "/plugins/file?name=docker&f=js/docker.js", function(){
pluginService('docker', $('.plugin_version').attr('version'));
});
</script>
+860
View File
@@ -0,0 +1,860 @@
# 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 docker
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getDClient():
try:
client = docker.from_env()
except Exception as e:
client = docker.DockerClient(
base_url='unix:///Users/midoks/.docker/run/docker.sock')
return client
def getPluginName():
return 'docker'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getConf():
path = getServerDir() + "/redis.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[2:]
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(self, data, ck=[]):
for i in range(len(ck)):
print(data[i])
if not ck[i] in data:
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
return (True, mw.returnJson(True, 'ok'))
def status():
data = mw.execShell(
"ps -ef|grep docker |grep -v grep | grep -v python | grep -v mdserver-web | awk '{print $2}'")
if data[0] == '':
return 'stop'
return 'start'
def initDreplace():
return ''
def dockerOp(method):
file = initDreplace()
if not mw.isAppleSystem():
data = mw.execShell('systemctl ' + method + ' docker')
if data[1] == '':
return 'ok'
return data[1]
return 'fail'
def start():
return dockerOp('start')
def stop():
return dockerOp('stop')
def restart():
status = dockerOp('restart')
log_file = runLog()
mw.execShell("echo '' > " + log_file)
return status
def reload():
return dockerOp('reload')
def initdStatus():
if mw.isAppleSystem():
return "Apple Computer does not support"
shell_cmd = 'systemctl status ' + \
getPluginName() + ' | grep loaded | grep "enabled;"'
data = mw.execShell(shell_cmd)
if data[0] == '':
return 'fail'
return 'ok'
def initdInstall():
if mw.isAppleSystem():
return "Apple Computer does not support"
mw.execShell('systemctl enable ' + getPluginName())
return 'ok'
def initdUinstall():
if mw.isAppleSystem():
return "Apple Computer does not support"
mw.execShell('systemctl disable ' + getPluginName())
return 'ok'
# UTC时间转换为时间戳
def utc_to_local(utc_time_str, utc_format='%Y-%m-%dT%H:%M:%S'):
import pytz
import datetime
import time
local_tz = pytz.timezone('Asia/Chongqing')
local_format = "%Y-%m-%d %H:%M"
utc_dt = datetime.datetime.strptime(utc_time_str, utc_format)
local_dt = utc_dt.replace(tzinfo=pytz.utc).astimezone(local_tz)
time_str = local_dt.strftime(local_format)
return int(time.mktime(time.strptime(time_str, local_format)))
def conList():
c = getDClient()
clist = c.containers.list(all=True)
conList = []
for con in clist:
tmp = con.attrs
tmp['Created'] = utc_to_local(tmp['Created'].split('.')[0])
conList.append(tmp)
return conList
def conListData():
try:
clist = conList()
except Exception as e:
return mw.returnJson(False, '未开启Docker')
return mw.returnJson(True, 'ok', clist)
def dockerRemoveCon():
args = getArgs()
data = checkArgs(args, ['Hostname'])
if not data[0]:
return data[1]
Hostname = args['Hostname']
c = getDClient()
try:
conFind = c.containers.get(Hostname)
try:
path_list = conFind.attrs['GraphDriver'][
'Data']['LowerDir'].split(':')
for i in path_list:
mw.execShell('chattr -R -i %s' % i)
except:
pass
conFind.remove(force=True)
return mw.returnJson(True, '成功删除!')
except docker.errors.APIError as ex:
return mw.returnJson(False, '删除失败!' + str(ex))
def dockerLogCon():
args = getArgs()
data = checkArgs(args, ['Hostname'])
if not data[0]:
return data[1]
Hostname = args['Hostname']
c = getDClient()
try:
conFind = c.containers.get(Hostname)
if not conFind:
return mw.returnJson(False, 'The specified container does not exist!')
log = conFind.logs()
if not isinstance(log, str):
log = log.decode()
return mw.returnJson(True, log)
except docker.errors.APIError as ex:
return mw.returnJson(False, 'Get Logs failed')
def dockerRunCon():
# 启动容器
args = getArgs()
data = checkArgs(args, ['Hostname'])
if not data[0]:
return data[1]
Hostname = args['Hostname']
c = getDClient()
try:
conFind = c.containers.get(Hostname)
if not conFind:
return mw.returnJson(False, 'The specified container does not exist!')
conFind.start()
return mw.returnJson(True, '启动成功!')
except docker.errors.APIError as ex:
return mw.returnJson(False, '启动失败!' + str(ex))
def dockerStopCon():
# 停止容器
args = getArgs()
data = checkArgs(args, ['Hostname'])
if not data[0]:
return data[1]
Hostname = args['Hostname']
c = getDClient()
try:
conFind = c.containers.get(Hostname)
if not conFind:
return mw.returnJson(False, 'The specified container does not exist!')
conFind.stop()
return mw.returnJson(True, '停止成功!')
except docker.errors.APIError as ex:
return mw.returnJson(False, '停止失败!' + str(ex))
def dockerExec():
# 容器执行命令
args = getArgs()
data = checkArgs(args, ['Hostname'])
if not data[0]:
return data[1]
Hostname = args['Hostname']
debug_path = 'data/debug.pl'
if os.path.exists(debug_path):
return mw.returnJson(False, '开发模式不能进入!')
c = getDClient()
try:
conFind = c.containers.get(Hostname)
cmd = 'docker container exec -it %s /bin/sh' % Hostname
return mw.returnJson(True, cmd)
except docker.errors.APIError as ex:
return mw.returnJson(False, '连接失败!')
def imageList():
imageList = []
c = getDClient()
ilist = c.images.list()
for image in ilist:
tmp_attrs = image.attrs
if len(tmp_attrs['RepoTags']) == 1:
tmp_image = {}
tmp_image['Id'] = tmp_attrs['Id'].split(':')[1][:12]
tmp_image['RepoTags'] = tmp_attrs['RepoTags'][0]
tmp_image['Size'] = tmp_attrs['Size']
tmp_image['Labels'] = tmp_attrs['Config']['Labels']
tmp_image['Comment'] = tmp_attrs['Comment']
tmp_image['Created'] = utc_to_local(
tmp_attrs['Created'].split('.')[0])
imageList.append(tmp_image)
else:
for i in range(len(tmp_attrs['RepoTags'])):
tmp_image = {}
tmp_image['Id'] = tmp_attrs['Id'].split(':')[1][:12]
tmp_image['RepoTags'] = tmp_attrs['RepoTags'][i]
tmp_image['Size'] = tmp_attrs['Size']
tmp_image['Labels'] = tmp_attrs['Config']['Labels']
tmp_image['Comment'] = tmp_attrs['Comment']
tmp_image['Created'] = utc_to_local(
tmp_attrs['Created'].split('.')[0])
imageList.append(tmp_image)
imageList = sorted(imageList, key=lambda x: x['Created'], reverse=True)
return imageList
def dockerPull():
# pull Dockr 官方镜像
args = getArgs()
data = checkArgs(args, ['images'])
if not data[0]:
return data[1]
images = args['images']
if ':' in images:
pass
else:
images = images + ':latest'
c = getDClient()
try:
ret = c.images.pull(images)
if ret:
return mw.returnJson(True, '拉取成功!')
else:
return mw.returnJson(False, '拉取失败,请检查镜像名称或是否需要登录docker进行下载')
except:
ret = mw.execShell('docker image pull %s' % images)
if 'invalid' in ret[-1]:
return mw.returnJson(False, '拉取失败,请检查镜像名称或是否需要登录docker进行下载')
else:
return mw.returnJson(True, '拉取成功!')
def dockerPlulPath(path):
if not path and path == '':
return mw.returnJson(False, 'Invalid address')
ret = mw.execShell('docker image pull %s' % path)
if 'invalid' in ret[-1]:
return mw.returnJson(False, '拉取失败,请检查镜像名称或是否需要登录docker进行下载')
else:
return mw.returnJson(True, '拉取成功!')
def dockerPullReg():
# pull Dockr 官方镜像
args = getArgs()
data = checkArgs(args, ['path'])
if not data[0]:
return data[1]
path = args['path']
return dockerPlulPath(path)
# 判断镜像是否存在
def checkImage(path):
image_list = imageList()
for i in image_list:
if path == i["RepoTags"]:
return mw.returnData(False, '镜像已存在!')
def dockerPullPrivateNew():
# pull Dockr 官方镜像
args = getArgs()
data = checkArgs(args, ['path'])
if not data[0]:
return data[1]
path = args['path']
check = checkImage(path)
if check:
return mw.getJson(check)
my_repo = repoList()
if not my_repo:
return mw.returnJson(False, '未登录任何私人存储库,请登录然后拉取')
return dockerPlulPath(path)
def imageListData():
try:
ilist = imageList()
except Exception as e:
return mw.returnJson(False, '未开启Docker')
return mw.returnJson(True, 'ok', ilist)
def dockerRemoveImage():
args = getArgs()
data = checkArgs(args, ['imageId', 'repoTags'])
if not data[0]:
return data[1]
repoTags = args['repoTags']
imageId = args['imageId']
c = getDClient()
try:
c.images.remove(repoTags)
return mw.returnJson(True, '成功删除')
except:
try:
c.images.remove(imageId)
return mw.returnJson(True, '成功删除!')
except docker.errors.APIError as ex:
return mw.returnJson(False, '删除失败, 当前镜像正在使用!')
def getImageListFunc(dbname=''):
bkDir = mw.getRootDir() + '/backup/docker'
blist = os.listdir(bkDir)
r = []
bname = 'db_' + dbname
blen = len(bname)
for x in blist:
fbstr = x[0:blen]
if fbstr == bname:
r.append(x)
return r
def dockerImagePickDir():
bkDir = mw.getRootDir() + '/backup/docker'
return mw.returnJson(True, 'ok', bkDir)
def dockerImagePickList():
bkDir = mw.getRootDir() + '/backup/docker'
if not os.path.exists(bkDir):
os.mkdir(bkDir)
r = os.listdir(bkDir)
rr = []
for x in range(0, len(r)):
p = bkDir + '/' + r[x]
data = {}
data['name'] = r[x]
rsize = os.path.getsize(p)
data['size'] = mw.toSize(rsize)
t = os.path.getctime(p)
t = time.localtime(t)
data['time'] = time.strftime('%Y-%m-%d %H:%M:%S', t)
rr.append(data)
data['file'] = p
return mw.returnJson(True, 'ok', rr)
def dockerImagePickSave():
# image 导出
args = getArgs()
data = checkArgs(args, ['images'])
if not data[0]:
return data[1]
bkDir = mw.getRootDir() + '/backup/docker/'
images = args['images']
try:
file_name = bkDir + \
str(time.strftime('%Y%m%d_%H%M%S', time.localtime())) + '.tar.gz'
mw.execShell('docker image save %s | gzip > %s' %
(images, file_name))
return mw.returnJson(True, '导出镜像 {} 成功!'.format(file_name))
except docker.errors.APIError as ex:
return mw.returnJson(False, '操作失败: ' + str(ex))
def dockerImagePickLoad():
# 镜像文件导入
args = getArgs()
data = checkArgs(args, ['file'])
if not data[0]:
return data[1]
try:
file_path = args['file']
if not os.path.exists(file_path):
return mw.returnJson(False, '文件不存在')
if file_path.endswith('.tar'):
mw.execShell('docker image load < %s' % file_path)
elif file_path.endswith('.tar.gz'):
mw.execShell('gunzip -c %s | docker image load' % file_path)
else:
return mw.returnJson(False, '不支持改文件类型!')
return mw.returnJson(True, '导入镜像文件成功!')
except docker.errors.APIError as ex:
return mw.returnJson(False, '操作失败: ' + str(ex))
def dockerLoginCheck(user_name, user_pass, registry):
# 登陆验证
cmd = 'docker login -u=%s -p %s %s' % (user_name, user_pass, registry)
# print(cmd)
login_test = mw.execShell(cmd)
# print(login_test)
ret = 'required$|Error'
ret2 = re.findall(ret, login_test[-1])
if len(ret2) == 0:
return True
else:
return False
def getDockerIpListData():
# 取IP列表
path = getServerDir()
ipConf = path + '/iplist.json'
if not os.path.exists(ipConf):
return []
iplist = json.loads(mw.readFile(ipConf))
return iplist
def getDockerIpList():
data = getDockerIpListData()
return mw.returnJson(True, 'ok!', data)
def dockerAddIP():
# 添加IP
args = getArgs()
data = checkArgs(args, ['address', 'netmask', 'gateway'])
if not data[0]:
return data[1]
path = getServerDir()
ipConf = path + '/iplist.json'
if not os.path.exists(ipConf):
iplist = []
mw.writeFile(ipConf, json.dumps(iplist))
iplist = json.loads(mw.readFile(ipConf))
ipInfo = {
'address': args['address'],
'netmask': args['netmask'],
'gateway': args['gateway'],
}
iplist.append(ipInfo)
mw.writeFile(ipConf, json.dumps(iplist))
return mw.returnJson(True, '添加成功!')
def dockerDelIP():
# 删除IP
args = getArgs()
data = checkArgs(args, ['address'])
if not data[0]:
return data[1]
path = getServerDir()
ipConf = path + '/iplist.json'
if not os.path.exists(ipConf):
return mw.returnJson(False, '指定的IP不存在。!')
iplist = json.loads(mw.readFile(ipConf))
newList = []
for ipInfo in iplist:
if ipInfo['address'] == args['address']:
continue
newList.append(ipInfo)
mw.writeFile(ipConf, json.dumps(newList))
return mw.returnJson(True, '成功删除!')
def getDockerCreateInfo():
# 取创建依赖
import psutil
data = {}
data['images'] = imageList()
data['memSize'] = int(psutil.virtual_memory().total / 1024 / 1024)
data['iplist'] = getDockerIpListData()
return mw.returnJson(True, 'ok!', data)
def __release_port(port):
from collections import namedtuple
try:
import firewall_api
firewall_api.firewall_api().addAcceptPortArgs(port, 'docker', 'port')
return port
except Exception as e:
return "Release failed {}".format(e)
def dockerPortCheck():
args = getArgs()
data = checkArgs(args, ['port'])
if not data[0]:
return data[1]
port = args['port']
is_ok = IsPortExists(port)
if is_ok:
return mw.returnJson(True, 'ok')
return mw.returnJson(False, 'fail')
def IsPortExists(port):
# 判断端口是否被占用
ret = __check_dst_port(ip='localhost', port=port)
ret2 = __check_dst_port(ip='0.0.0.0', port=port)
if ret:
return ret
if not ret and ret2:
return ret2
if not ret and not ret2:
return False
def __check_dst_port(ip, port, timeout=3):
# 端口检测
import socket
ok = True
try:
s = socket.socket()
s.settimeout(timeout)
s.connect((ip, port))
s.close()
except:
ok = False
return ok
def dockerCreateCon():
args = getArgs()
data = checkArgs(args, ['environments', 'command',
'entrypoint', 'image', 'mem_limit', 'ports', 'volumes'])
if not data[0]:
return data[1]
environments = args['environments']
environments = environments.strip().split()
command = args['command']
entrypoint = args['entrypoint']
image = args['image']
mem_limit = args['mem_limit']
ports = args['ports']
ports = ports.replace('[', '(').replace(']', ')')
volumes = args['volumes']
# if __name__ == "__main__":
# print(args)
try:
c = getDClient()
conObject = c.containers.run(
image=image,
mem_limit=mem_limit + 'M',
ports=eval(ports),
auto_remove=False,
command=command,
detach=True,
stdin_open=True,
tty=True,
entrypoint=entrypoint,
privileged=True,
volumes=json.loads(volumes),
cpu_shares=10,
environment=environments
)
if conObject:
__release_port(ports)
return mw.returnJson(True, '创建成功!')
return mw.returnJson(False, '创建失败!')
except docker.errors.APIError as ex:
return mw.returnJson(False, '创建失败!' + str(ex))
def dockerLogin():
args = getArgs()
# print(args)
data = checkArgs(args, ['user', 'passwd', 'hub_name',
'namespace', 'registry', 'repository_name'])
if not data[0]:
return data[1]
user_name = args['user']
user_pass = args['passwd']
registry = args['registry']
hub_name = args['hub_name']
namespace = args['namespace']
repository_name = args['repository_name']
ret_status = dockerLoginCheck(user_name, user_pass, registry)
path = getServerDir()
if ret_status:
user_file = path + '/user.json'
user_info = mw.readFile(user_file)
if not user_info:
user_info = []
else:
user_info = json.loads(user_info)
ret = {}
ret['user_name'] = user_name
ret['user_pass'] = user_pass
ret['registry'] = registry
ret['hub_name'] = hub_name
ret['namespace'] = namespace
ret['repository_name'] = repository_name
if not registry:
ret['registry'] = "docker.io"
user_info.append(ret)
mw.writeFile(user_file, json.dumps(user_info))
return mw.returnJson(True, '成功登录!')
return mw.returnJson(False, '登录失败!')
# 删除用户信息
def delete_user_info(registry):
path = getServerDir()
user_file = path + '/user.json'
user_info = mw.readFile(user_file)
if user_info:
user_info = json.loads(user_info)
for i in range(len(user_info)):
if registry in user_info[i].values():
del(user_info[i])
mw.writeFile(user_file, json.dumps(user_info))
return True
def dockerLogout():
args = getArgs()
data = checkArgs(args, ['registry'])
if not data[0]:
return data[1]
registry = args['registry']
if registry == "docker.io":
registry = ""
login_test = mw.execShell('docker logout %s' % registry)
if registry == "":
registry = "docker.io"
ret = 'required$|Error'
ret2 = re.findall(ret, login_test[-1])
delete_user_info(registry)
if len(ret2) == 0:
return mw.returnJson(True, '退出成功')
else:
return mw.returnJson(True, '退出失败')
def repoList():
path = getServerDir()
repostory_info = []
user_file = path + '/user.json'
if os.path.exists(user_file):
user_info = mw.readFile(user_file)
user_info = json.loads(user_info)
for i in user_info:
tmp = {}
tmp["hub_name"] = i["hub_name"]
tmp["registry"] = i["registry"]
tmp["namespace"] = i["namespace"]
tmp['repository_name'] = i["repository_name"]
repostory_info.append(tmp)
return mw.returnJson(True, 'ok', repostory_info)
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 == 'conf':
print(getConf())
elif func == 'con_list':
print(conListData())
elif func == 'docker_con_log':
print(dockerLogCon())
elif func == 'docker_remove_con':
print(dockerRemoveCon())
elif func == 'docker_run_con':
print(dockerRunCon())
elif func == 'docker_stop_con':
print(dockerStopCon())
elif func == 'docker_exec':
print(dockerExec())
elif func == 'docker_pull':
print(dockerPull())
elif func == 'docker_pull_reg':
print(dockerPullReg())
elif func == 'image_list':
print(imageListData())
elif func == 'image_pick_dir':
print(dockerImagePickDir())
elif func == 'image_pick_save':
print(dockerImagePickSave())
elif func == 'image_pick_load':
print(dockerImagePickLoad())
elif func == 'image_pick_list':
print(dockerImagePickList())
elif func == 'docker_get_iplist':
print(getDockerIpList())
elif func == 'docker_del_ip':
print(dockerDelIP())
elif func == 'docker_add_ip':
print(dockerAddIP())
elif func == 'get_docker_create_info':
print(getDockerCreateInfo())
elif func == 'docker_create_con':
print(dockerCreateCon())
elif func == 'docker_remove_image':
print(dockerRemoveImage())
elif func == 'docker_port_check':
print(dockerPortCheck())
elif func == 'docker_login':
print(dockerLogin())
elif func == 'docker_logout':
print(dockerLogout())
elif func == 'repo_list':
print(repoList())
else:
print('error')
+19
View File
@@ -0,0 +1,19 @@
{
"sort": 7,
"ps": "Docker是一个开源的应用容器引擎",
"name": "docker",
"title": "Docker",
"shell": "install.sh",
"versions":["1.0"],
"updates":["1.0"],
"tip": "soft",
"checks": "server/docker",
"path": "server/docker",
"display": 1,
"author": "Zend",
"date": "2017-04-01",
"home": "https://docker.io",
"doc1":"https://docker-py.readthedocs.io/",
"type": 0,
"pid": "2"
}
+84
View File
@@ -0,0 +1,84 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
# cd /www/server/mdserver-web/plugins/docker && /bin/bash install.sh uninstall 1.0
# cd /www/server/mdserver-web/plugins/docker && /bin/bash install.sh install 1.0
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
if [ -f ${rootPath}/bin/activate ];then
source ${rootPath}/bin/activate
fi
Install_Docker()
{
# which docker
# if [ "$?" == "0" ];then
# echo '安装已经完成docker' > $install_tmp
# exit 0
# fi
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/source
if [ ! -d $serverPath/docker ];then
curl -fsSL https://get.docker.com | bash
mkdir -p $serverPath/docker
fi
pip install docker
pip install pytz
if [ -d $serverPath/docker ];then
echo "${VERSION}" > $serverPath/docker/version.pl
echo '安装完成' > $install_tmp
cd ${rootPath} && python3 ${rootPath}/plugins/docker/index.py start
cd ${rootPath} && python3 ${rootPath}/plugins/docker/index.py initd_install
fi
}
Uninstall_Docker()
{
CMD=yum
which apt
if [ "$?" == "0" ];then
CMD=apt
fi
if [ -f /usr/lib/systemd/system/docker.service ];then
systemctl stop docker
systemctl disable docker
rm -rf /usr/lib/systemd/system/docker.service
systemctl daemon-reload
fi
$CMD remove -y docker docker-ce-cli containerd.io
# docker-client \
# docker-client-latest \
# docker-common \
# docker-latest \
# docker-latest-logrotate \
# docker-logrotate \
# docker-selinux \
# docker-engine-selinux \
# docker-engine \
# docker-ce
rm -rf $serverPath/docker
echo "Uninstall_Docker" > $install_tmp
}
action=$1
if [ "${1}" == 'install' ];then
Install_Docker
else
Uninstall_Docker
fi
+1084
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,8 +1,8 @@
{
"ps": "Gitea 是一个开源社区驱动的轻量级代码托管解决方案。",
"ps": "Gitea是一个开源社区驱动的轻量级代码托管解决方案。",
"name": "gitea",
"title": "Gitea",
"versions": ["1.17.2"],
"versions": ["1.17.2","1.18.5"],
"tip": "soft",
"install_pre_inspection":false,
"uninstall_pre_inspection":true,
+1 -1
View File
@@ -14,7 +14,7 @@ if [ -f ${rootPath}/bin/activate ];then
fi
URL_DOWNLOAD=https://dl.gitea.io/
URL_DOWNLOAD=https://dl.gitea.com
bash ${rootPath}/scripts/getos.sh
+2 -2
View File
@@ -739,7 +739,7 @@ def importDbBackup():
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
sock = getSocketFile()
mysql_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p' + pwd + \
mysql_cmd = getServerDir() + '/bin/mariadb -S ' + sock + ' -uroot -p' + pwd + \
' ' + name + ' < ' + file_path_sql
# print(mysql_cmd)
@@ -800,7 +800,7 @@ def importDbExternal():
sock = getSocketFile()
os.environ["MYSQL_PWD"] = pwd
mysql_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p' + \
mysql_cmd = getServerDir() + '/bin/mariadb -S ' + sock + ' -uroot -p' + \
pwd + ' ' + name + ' < ' + import_sql
# print(mysql_cmd)
+1 -1
View File
@@ -39,7 +39,7 @@ max_connections = 500
max_connect_errors = 100
open_files_limit = 65535
skip-name-resolve=1
skip_name_resolve=1
#skip-grant-tables
#skip-networking
#skip-external-locking
+1 -1
View File
@@ -41,7 +41,7 @@ max_connections = 500
max_connect_errors = 100
open_files_limit = 65535
skip-name-resolve=1
skip_name_resolve=1
#skip-grant-tables
#skip-networking
#skip-external-locking
+3 -2
View File
@@ -17,6 +17,7 @@ datadir = {$SERVER_APP_PATH}/data
log-error = {$SERVER_APP_PATH}/data/error.log
server-id = {$SERVER_ID}
explicit_defaults_for_timestamp=true
default_storage_engine = InnoDB
@@ -40,7 +41,7 @@ max_connect_errors = 100
open_files_limit = 2560
max_allowed_packet = 128M
skip_name_resolve = 1
skip_name_resolve=1
skip-ssl
#skip-networking
#skip-external-locking
@@ -95,7 +96,7 @@ innodb_file_per_table = 1
innodb_large_prefix = 1
secure-file-priv={$SERVER_APP_PATH}/tmp
#secure-file-priv=disabled
[mysqldump]
quick
+3 -3
View File
@@ -8,8 +8,8 @@ default-character-set = UTF8MB4
[mysqld]
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
sha256_password_private_key_path=mysql.pem
sha256_password_public_key_path=mysql.pub
sha256_password_private_key_path={$SERVER_APP_PATH}/data/mysql.pem
sha256_password_public_key_path={$SERVER_APP_PATH}/data/mysql.pub
authentication_policy=mysql_native_password
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
@@ -40,7 +40,7 @@ max_connect_errors = 100
open_files_limit = 2560
max_allowed_packet = 128M
skip_name_resolve = 1
skip_name_resolve=1
#skip-networking
#skip-external-locking
#loose-skip-innodb
+22 -11
View File
@@ -167,7 +167,6 @@ def pMysqlDb():
def makeInitRsaKey(version=''):
datadir = getServerDir() + "/data"
mysql_pem = datadir + "/mysql.pem"
if not os.path.exists(mysql_pem):
rdata = mw.execShell(
@@ -176,12 +175,11 @@ def makeInitRsaKey(version=''):
rdata = mw.execShell(
'cd ' + datadir + ' && openssl rsa -in mysql.pem -pubout -out mysql.pub')
# print(rdata)
if not mw.isAppleSystem():
mw.execShell('cd ' + datadir + ' && chmod 400 mysql.pem')
mw.execShell('cd ' + datadir + ' && chmod 444 mysql.pub')
mw.execShell('cd ' + datadir + ' && chown mysql:mysql mysql.pem')
mw.execShell('cd ' + datadir + ' && chown mysql:mysql mysql.pub')
if not mw.isAppleSystem():
mw.execShell('cd ' + datadir + ' && chmod 400 mysql.pem')
mw.execShell('cd ' + datadir + ' && chmod 444 mysql.pub')
mw.execShell('cd ' + datadir + ' && chown mysql:mysql mysql.pem')
mw.execShell('cd ' + datadir + ' && chown mysql:mysql mysql.pub')
def initDreplace(version=''):
@@ -251,6 +249,14 @@ def initDreplace(version=''):
return file_bin
def process_status():
cmd = "ps -ef|grep mysql |grep -v grep | grep -v python | awk '{print $2}'"
data = mw.execShell(cmd)
if data[0] == '':
return 'stop'
return 'start'
def status(version=''):
path = getConf()
if not os.path.exists(path):
@@ -383,7 +389,7 @@ def initMysql57Data():
myconf = serverdir + "/etc/my.cnf"
user = pGetDbUser()
cmd = 'cd ' + serverdir + ' && ./bin/mysqld --defaults-file=' + myconf + \
' --initialize-insecure --explicit_defaults_for_timestamp'
' --initialize-insecure --explicit_defaults_for_timestamp --user=mysql'
data = mw.execShell(cmd)
# print(data)
return False
@@ -450,7 +456,7 @@ def initMysqlPwd():
def initMysql8Pwd():
time.sleep(2)
time.sleep(8)
serverdir = getServerDir()
myconf = serverdir + "/etc/my.cnf"
@@ -540,7 +546,12 @@ def my8cmd(version, method):
else:
mw.execShell('systemctl start mysql')
initMysql8Pwd()
for x in range(10):
mydb_status = process_status()
if mydb_status == 'start':
initMysql8Pwd()
break
time.sleep(1)
if mw.isAppleSystem():
cmd_init_stop = init_file + ' stop'
@@ -562,11 +573,11 @@ def my8cmd(version, method):
def appCMD(version, action):
makeInitRsaKey(version)
if version == '8.0' or version == '5.7':
status = my8cmd(version, action)
else:
status = myOp(version, action)
makeInitRsaKey(version)
return status
+1 -1
View File
@@ -181,7 +181,7 @@ function changeMySQLDataPath(act) {
$.post('/database?action=GetMySQLInfo', '', function(rdata) {
var LimitCon = '<p class="conf_p">\
<input id="datadir" class="phpUploadLimit bt-input-text mr5" style="width:350px;" type="text" value="' + rdata.datadir + '" name="datadir">\
<span onclick="ChangePath(\'datadir\')" class="glyphicon glyphicon-folder-open cursor mr20" style="width:auto"></span><button class="btn btn-success btn-sm" onclick="changeMySQLDataPath(1)">' + lan.soft.mysql_to + '</button>\
<span onclick="changePath(\'datadir\')" class="glyphicon glyphicon-folder-open cursor mr20" style="width:auto"></span><button class="btn btn-success btn-sm" onclick="changeMySQLDataPath(1)">' + lan.soft.mysql_to + '</button>\
</p>';
$(".soft-man-con").html(LimitCon);
});
+1
View File
@@ -86,6 +86,7 @@ Install_mysql()
make -j${cpuCore} && make install && make clean
if [ -d $serverPath/mysql ];then
rm -rf ${mysqlDir}/mysql-${VERSION}
echo '5.5' > $serverPath/mysql/version.pl
echo '安装完成' > $install_tmp
else
+1
View File
@@ -105,6 +105,7 @@ Install_mysql()
if [ -d $serverPath/mysql ];then
rm -rf ${mysqlDir}/mysql-${VERSION}
echo '5.6' > $serverPath/mysql/version.pl
echo '安装完成' > $install_tmp
else
+1
View File
@@ -118,6 +118,7 @@ Install_mysql()
make -j${cpuCore} && make install && make clean
if [ -d $serverPath/mysql ];then
rm -rf ${mysqlDir}/mysql-${VERSION}
echo '5.7' > $serverPath/mysql/version.pl
echo '安装完成' > $install_tmp
else
+1
View File
@@ -210,6 +210,7 @@ Install_mysql()
make -j${cpuCore} && make install && make clean
if [ -d $serverPath/mysql ];then
rm -rf ${mysqlDir}/mysql-${VERSION}
echo '8.0' > $serverPath/mysql/version.pl
echo '安装完成' > $install_tmp
else
Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

+26
View File
@@ -0,0 +1,26 @@
<div class="bt-form">
<div class="bt-w-main">
<div class='plugin_version'></div>
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('nezha',$('.plugin_version').attr('version'));">面板服务</p>
<p onclick="pluginInitD('nezha',$('.plugin_version').attr('version'));">面板自启动</p>
<p onclick="nezha.cfg($('.plugin_version').attr('version'));">面板配置</p>
<p onclick="pluginConfig('nezha', $('.plugin_version').attr('version'), 'conf');">面板配置文件</p>
<p onclick="pluginService('nezha', $('.plugin_version').attr('version'), 'agent');">AGENT服务</p>
<p onclick="pluginInitD('nezha', $('.plugin_version').attr('version'), 'agent');">AGENT自启动</p>
<p onclick="nezha.agent_cfg($('.plugin_version').attr('version'));">AGENT配置</p>
<p onclick="nezha.readme();">说明</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<script type="text/javascript">
resetPluginWinHeight(530);
$.getScript( "/plugins/file?name=nezha&f=js/nezha.js", function(){
nezha.init();
pluginService('nezha');
});
</script>
+364
View File
@@ -0,0 +1,364 @@
# coding:utf-8
import sys
import io
import os
import time
import re
import socket
import json
from datetime import datetime
sys.path.append(os.getcwd() + "/class/core")
import mw
app_debug = False
if mw.isAppleSystem():
app_debug = True
class App:
__setupPath = '/www/server/nezha'
__cfg = ''
__agent_cfg = ''
def __init__(self):
self.__setupPath = self.getServerDir()
self.__cfg = self.__setupPath + '/nezha.cfg'
self.__agent_cfg = self.__setupPath + '/agent.cfg'
def getArgs(self):
args = sys.argv[3:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':', 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(self, 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 __release_port(self, port):
from collections import namedtuple
try:
import firewall_api
firewall_api.firewall_api().addAcceptPortArgs(port, 'nezha', 'port')
return port
except Exception as e:
return "Release failed {}".format(e)
def openPort(self):
for i in ["9527", "5555"]:
self.__release_port(i)
return True
def getPluginName(self):
return 'nezha'
def getPluginDir(self):
return mw.getPluginDir() + '/' + self.getPluginName()
def getServerDir(self):
return mw.getServerDir() + '/' + self.getPluginName()
def getInitdConfTpl(self):
path = self.getPluginDir() + "/init.d/nezha.tpl"
return path
def getInitdAgentConfTpl(self):
path = self.getPluginDir() + "/init.d/nezha-agent.tpl"
return path
def getHomeDir(self):
if mw.isAppleSystem():
user = mw.execShell(
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
return '/Users/' + user
else:
return '/root'
def getRunUser(self):
if mw.isAppleSystem():
user = mw.execShell(
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
return user
else:
return 'root'
def status(self):
cmd = "ps -ef|grep " + self.getPluginName() + \
" |grep -v grep | grep -v nezha-agent | grep -v python | awk '{print $2}'"
data = mw.execShell(cmd)
if data[0] == '':
return "stop"
return 'start'
def status_agent(self):
cmd = "ps -ef | grep nezha-agent | grep -v grep | grep -v python | awk '{print $2}'"
data = mw.execShell(cmd)
if data[0] == '':
return 'stop'
return 'start'
def contentReplace(self, content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$RUN_USER}', self.getRunUser())
content = content.replace('{$HOME_DIR}', self.getHomeDir())
return content
def initDreplace(self):
file_tpl = self.getInitdConfTpl()
service_path = mw.getServerDir()
initD_path = self.getServerDir() + '/init.d'
if not os.path.exists(initD_path):
os.mkdir(initD_path)
self.openPort()
file_bin = initD_path + '/' + self.getPluginName()
if not os.path.exists(file_bin):
content = mw.readFile(file_tpl)
content = self.contentReplace(content)
mw.writeFile(file_bin, content)
mw.execShell('chmod +x ' + file_bin)
# systemd
systemDir = mw.systemdCfgDir()
systemService = systemDir + '/nezha.service'
systemServiceTpl = self.getPluginDir() + '/init.d/nezha.service.tpl'
if os.path.exists(systemDir) and not os.path.exists(systemService):
service_path = mw.getServerDir()
se_content = mw.readFile(systemServiceTpl)
se_content = self.contentReplace(se_content)
mw.writeFile(systemService, se_content)
mw.execShell('systemctl daemon-reload')
return file_bin
def contentAgentReplace(self, content):
path = self.__agent_cfg
if os.path.exists(path):
data = self.get_agent_cfg()
content = content.replace('{$APP_HOST}', data['host'])
content = content.replace('{$APP_SECRET}', data['secret'])
return content
def initDAgent(self):
file_tpl = self.getInitdAgentConfTpl()
initD_path = self.getServerDir() + '/init.d'
if not os.path.exists(initD_path):
os.mkdir(initD_path)
file_agent_bin = initD_path + '/nezha-agent'
content = mw.readFile(file_tpl)
content = self.contentReplace(content)
content = self.contentAgentReplace(content)
mw.writeFile(file_agent_bin, content)
mw.execShell('chmod +x ' + file_agent_bin)
# systemd
sysDir = mw.systemdCfgDir()
sysService = sysDir + '/nezha-agent.service'
sysServiceTpl = self.getPluginDir() + '/init.d/nezha-agent.service.tpl'
service_path = mw.getServerDir()
content = mw.readFile(sysServiceTpl)
content = self.contentReplace(content)
content = self.contentAgentReplace(content)
mw.writeFile(sysService, content)
mw.execShell('systemctl daemon-reload')
return file_agent_bin
def init_cfg(self):
self.initDreplace()
self.initDAgent()
def imOp(self, method):
file = self.initDreplace()
if not mw.isAppleSystem():
cmd = 'systemctl {} {}'.format(method, self.getPluginName())
data = mw.execShell(cmd)
if data[1] == '':
return 'ok'
return 'fail'
data = mw.execShell(file + ' ' + method)
if data[1] == '':
return 'ok'
return data[0]
def start(self):
return self.imOp('start')
def stop(self):
return self.imOp('stop')
def restart(self):
return self.imOp('restart')
def reload(self):
return self.imOp('reload')
def agOp(self, method):
file = self.initDAgent()
path = self.__agent_cfg
if not os.path.exists(path):
return '请先设置Agent配置!'
if not mw.isAppleSystem():
cmd = 'systemctl {} {}'.format(method, 'nezha-agent')
data = mw.execShell(cmd)
if data[1] == '':
return 'ok'
return 'fail'
data = mw.execShell(file + ' ' + method)
if data[1] == '':
return 'ok'
return data[0]
def start_agent(self):
return self.agOp('start')
def stop_agent(self):
return self.agOp('stop')
def restart_agent(self):
return self.agOp('restart')
def reload_agent(self):
return self.agentOp('reload')
def initd_status(self):
cmd = 'systemctl status nezha | grep loaded | grep "enabled;"'
data = mw.execShell(cmd)
if data[0] == '':
return 'fail'
return 'ok'
def initd_install(self):
mw.execShell('systemctl enable nezha')
return 'ok'
def initd_uninstall(self):
mw.execShell('systemctl disable nezha')
return 'ok'
def initd_status_agent(self):
cmd = 'systemctl status nezha-agent | grep loaded | grep "enabled;"'
data = mw.execShell(cmd)
if data[0] == '':
return 'fail'
return 'ok'
def initd_install_agent(self):
mw.execShell('systemctl enable nezha-agent')
return 'ok'
def initd_uninstall_agent(self):
mw.execShell('systemctl disable nezha-agent')
return 'ok'
def conf(self):
return self.getServerDir() + '/dashboard/data/config.yaml'
def nezha_cfg(self):
path = self.__cfg
if not os.path.exists(path):
d = {}
cmd_un = 'cd ' + self.getServerDir() + '/dashboard && ./nezha conf -u ""'
mw.execShell(cmd_un)
td = mw.execShell(cmd_un)
d['username'] = td[0].strip()
pwd = mw.getRandomString(16)
cmd_pwd = 'cd ' + self.getServerDir() + '/dashboard && ./nezha conf -u "" -p ' + pwd
td = mw.execShell(cmd_pwd)
d['password'] = pwd
mw.writeFile(path, mw.enDoubleCrypt('nezha', mw.getJson(d)))
info = mw.readFile(path)
info = mw.deDoubleCrypt('nezha', info)
info = json.loads(info)
return mw.returnJson(True, 'ok', info)
def nezha_save_cfg(self):
args = self.getArgs()
data = self.checkArgs(args, ['username', 'password'])
if not data[0]:
return data[1]
path = self.__cfg
cmd = 'cd ' + self.getServerDir() + '/dashboard && ./nezha conf -su "' + \
args['username'] + '" -p ' + args['password']
# print(cmd)
t = mw.execShell(cmd)
# print(t)
mw.writeFile(path, mw.enDoubleCrypt('nezha', mw.getJson(args)))
return mw.returnJson(True, '修改成功!')
def get_agent_cfg(self):
path = self.__agent_cfg
info = mw.readFile(path)
info = mw.deDoubleCrypt('agent', info)
info = json.loads(info)
return info
def agent_cfg(self):
path = self.__agent_cfg
if not os.path.exists(path):
d = {}
d['host'] = '127.0.0.1:5555'
d['secret'] = 'secret'
mw.writeFile(path, mw.enDoubleCrypt('agent', mw.getJson(d)))
info = self.get_agent_cfg()
return mw.returnJson(True, 'ok', info)
def agent_save_cfg(self):
args = self.getArgs()
data = self.checkArgs(args, ['host', 'secret'])
if not data[0]:
return data[1]
path = self.__agent_cfg
mw.writeFile(path, mw.enDoubleCrypt('agent', mw.getJson(args)))
return mw.returnJson(True, '修改成功!')
def run_log(self):
return self.getServerDir() + '/logs/nezha.log'
if __name__ == "__main__":
func = sys.argv[1]
classApp = App()
try:
data = eval("classApp." + func + "()")
print(data)
except Exception as e:
print('error:' + str(e))
+18
View File
@@ -0,0 +1,18 @@
{
"sort": 7,
"ps": "哪吒监控面板/改造版",
"name": "nezha",
"title": "哪吒监控",
"shell": "install.sh",
"versions":["0.15.2"],
"tip": "soft",
"checks": "server/nezha",
"path": "server/nezha",
"display": 1,
"author": "midoks",
"date": "2023-06-26",
"home": "https://github.com/midoks/nezha",
"doc1": "https://nezha.wiki/",
"type": 0,
"pid": "5"
}
@@ -0,0 +1,30 @@
[Unit]
Description=Nezha Agent
After=syslog.target
#After=network.target
#After=nezha-dashboard.service
[Service]
# Modify these two values and uncomment them if you have
# repos with lots of files and get an HTTP error 500 because
# of that
###
#LimitMEMLOCK=infinity
#LimitNOFILE=65535
Type=simple
User=root
Group=root
WorkingDirectory={$SERVER_PATH}/nezha/agent/
ExecStart={$SERVER_PATH}/nezha/agent/nezha-agent -s {$APP_HOST} -p {$APP_SECRET}
Restart=always
#Environment=DEBUG=true
# Some distributions may not support these hardening directives. If you cannot start the service due
# to an unknown option, comment out the ones not supported by your version of systemd.
#ProtectSystem=full
#PrivateDevices=yes
#PrivateTmp=yes
#NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
+90
View File
@@ -0,0 +1,90 @@
#!/bin/bash
# chkconfig: 2345 55 25
# description: Nezha Agent Service
### BEGIN INIT INFO
# Provides: Nezha Agent
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts Nezha Agent
# Description: starts the Nezha Agent
### END INIT INFO
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
if [ -f /etc/init.d/functions ];then
. /etc/init.d/functions
fi
if [ -f /etc/rc.d/init.d/functions ];then
. /etc/rc.d/init.d/functions
fi
SERVICENAME=nezha-agent
LOG_PATH={$SERVER_PATH}/nezha/logs
APP_PATH={$SERVER_PATH}/nezha/agent
APP_HOST={$APP_HOST}
APP_SECRET={$APP_SECRET}
app_start(){
isStart=`ps -ef|grep "${SERVICENAME}" | grep -v grep | grep -v python | grep -v "/bin/bash" | awk '{print $2}'`
if [ "$isStart" == '' ];then
echo -e "Starting ${SERVICENAME}... \c"
cd $APP_PATH
exec nohup ${APP_PATH}/${SERVICENAME} -d -s ${APP_HOST} -p ${APP_SECRET} >> ${LOG_PATH}/${SERVICENAME}.log 2>&1 &
isStart=""
while [[ "$isStart" == "" ]];
do
echo -e ".\c"
sleep 0.5
isStart=$(ps -ef|grep "${SERVICENAME}" |grep -v grep | grep -v python | grep -v "/bin/bash" | awk '{print $2}')
let n+=1
if [ $n -gt 15 ];then
break;
fi
done
if [ "$isStart" == '' ];then
echo -e "\033[31mError: ${SERVICENAME} service startup failed.\033[0m"
return;
fi
echo -e "\033[32mdone\033[0m"
else
echo "Starting ${SERVICENAME}(pid $(echo $isStart)) already running"
fi
}
app_stop(){
pids=`ps -ef | grep "${SERVICENAME}" | grep -v grep | grep -v python | grep -v "/bin/bash" |awk '{print $2}'`
arr=($pids)
echo -e "Stopping ${SERVICENAME}... \c"
for p in ${arr[@]}
do
# echo "$p"
kill -9 $p
done
echo -e "\033[32mdone\033[0m"
}
app_status(){
isStart=`ps -ef | grep "${SERVICENAME}" | grep -v grep | grep -v python | grep -v "/bin/bash" | awk '{print $2}'`
if [ "$isStart" == '' ];then
echo -e "${SERVICENAME} not running"
else
echo -e "${SERVICENAME}(pid $(echo $isStart)) already running"
fi
}
case "$1" in
'start') app_start;;
'stop') app_stop;;
'status') app_status;;
'reload')
app_stop
app_start;;
'restart')
app_stop
app_start;;
esac
+30
View File
@@ -0,0 +1,30 @@
[Unit]
Description=Nezha Dashborad
After=syslog.target
After=network.target
After=mariadb.service mysqld.service postgresql.service memcached.service redis.service
[Service]
# Modify these two values and uncomment them if you have
# repos with lots of files and get an HTTP error 500 because
# of that
###
#LimitMEMLOCK=infinity
#LimitNOFILE=65535
Type=simple
#User=root
#Group=root
WorkingDirectory={$SERVER_PATH}/nezha/dashboard/
ExecStart={$SERVER_PATH}/nezha/dashboard/nezha web
Restart=always
#Environment=DEBUG=true
# Some distributions may not support these hardening directives. If you cannot start the service due
# to an unknown option, comment out the ones not supported by your version of systemd.
ProtectSystem=full
PrivateDevices=yes
PrivateTmp=yes
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
+87
View File
@@ -0,0 +1,87 @@
#!/bin/bash
# chkconfig: 2345 55 25
# description: Nezha Service
### BEGIN INIT INFO
# Provides: Nezha
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts Nezha
# Description: starts the Nezha
### END INIT INFO
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
if [ -f /etc/init.d/functions ];then
. /etc/init.d/functions
fi
if [ -f /etc/rc.d/init.d/functions ];then
. /etc/rc.d/init.d/functions
fi
SERVICENAME=nezha
LOG_PATH={$SERVER_PATH}/${SERVICENAME}/logs
APP_PATH={$SERVER_PATH}/${SERVICENAME}/dashboard
app_start(){
isStart=`ps -ef|grep "${SERVICENAME} web" | grep -v grep | grep -v python | grep -v "/bin/bash" | awk '{print $2}'`
if [ "$isStart" == '' ];then
echo -e "Starting ${SERVICENAME}... \c"
cd $APP_PATH && exec nohup ${APP_PATH}/${SERVICENAME} web >> ${LOG_PATH}/${SERVICENAME}.log 2>&1 &
isStart=""
while [[ "$isStart" == "" ]];
do
echo -e ".\c"
sleep 0.5
isStart=$(ps -ef|grep "${SERVICENAME} web" |grep -v grep | grep -v python | grep -v "/bin/bash" | awk '{print $2}')
let n+=1
if [ $n -gt 15 ];then
break;
fi
done
if [ "$isStart" == '' ];then
echo -e "\033[31mError: ${SERVICENAME} service startup failed.\033[0m"
return;
fi
echo -e "\033[32mdone\033[0m"
else
echo "Starting ${SERVICENAME}(pid $(echo $isStart)) already running"
fi
}
app_stop(){
pids=`ps -ef | grep "${SERVICENAME} web" | grep -v grep | grep -v python | grep -v "/bin/bash" |awk '{print $2}'`
arr=($pids)
echo -e "Stopping ${SERVICENAME}... \c"
for p in ${arr[@]}
do
# echo "$p"
kill -9 $p
done
echo -e "\033[32mdone\033[0m"
}
app_status(){
isStart=`ps -ef | grep "${SERVICENAME} web" | grep -v grep | grep -v python | grep -v "/bin/bash" | awk '{print $2}'`
if [ "$isStart" == '' ];then
echo -e "${SERVICENAME} not running"
else
echo -e "${SERVICENAME}(pid $(echo $isStart)) already running"
fi
}
case "$1" in
'start') app_start;;
'stop') app_stop;;
'status') app_status;;
'reload')
app_stop
app_start;;
'restart')
app_stop
app_start;;
esac
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
action=$1
type=$2
if [ "${2}" == "" ];then
echo '缺少安装脚本...' > $install_tmp
exit 0
fi
if [ ! -d $curPath/versions/$2 ];then
echo '缺少安装脚本2...' > $install_tmp
exit 0
fi
sh -x $curPath/versions/$2/install.sh $1
if [ "${action}" == "uninstall" ];then
if [ -f /usr/lib/systemd/system/nezha.service ] || [ -f /lib/systemd/system/nezha.service ] ;then
systemctl stop nezha
systemctl disable nezha
rm -rf /usr/lib/systemd/system/nezha.service
rm -rf /lib/systemd/system/nezha.service
systemctl daemon-reload
fi
if [ -f /usr/lib/systemd/system/nezha-agent.service ] || [ -f /lib/systemd/system/nezha-agent.service ] ;then
systemctl stop nezha-agent
systemctl disable nezha-agent
rm -rf /usr/lib/systemd/system/nezha-agent.service
rm -rf /lib/systemd/system/nezha-agent.service
systemctl daemon-reload
fi
fi
+184
View File
@@ -0,0 +1,184 @@
var nezha = {
plugin_name: 'nezha',
init: function () {
var _this = this;
},
send:function(info){
var tips = info['tips'];
var method = info['method'];
var args = info['data'];
var callback = info['success'];
var loadT = layer.msg(tips, { icon: 16, time: 0, shade: 0.3 });
var data = {};
data['name'] = 'nezha';
data['func'] = method;
data['version'] = $('.plugin_version').attr('version');
if (typeof(args) == 'string'){
data['args'] = JSON.stringify(toArrayObject(args));
} else {
data['args'] = JSON.stringify(args);
}
$.post('/plugins/run', data, function(res) {
layer.close(loadT);
if (!res.status){
layer.msg(res.msg,{icon:2,time:10000});
return;
}
var ret_data = $.parseJSON(res.data);
console.log("send:",ret_data);
// if (!ret_data.status){
// layer.msg(ret_data.msg,{icon:2,time:2000});
// return;
// }
// console.log("send2:",ret_data);
if(typeof(callback) == 'function'){
callback(ret_data);
}
},'json');
},
postCallback:function(info){
var tips = info['tips'];
var method = info['method'];
var args = info['data'];
var callback = info['success'];
var loadT = layer.msg(tips, { icon: 16, time: 0, shade: 0.3 });
var data = {};
data['name'] = 'nezha';
data['func'] = method;
data['version'] = $('.plugin_version').attr('version');
if (typeof(args) == 'string'){
data['args'] = JSON.stringify(toArrayObject(args));
} else {
data['args'] = JSON.stringify(args);
}
$.post('/plugins/callback', data, function(res) {
layer.close(loadT);
if (!res.status){
layer.msg(res.msg,{icon:2,time:10000});
return;
}
var ret_data = $.parseJSON(res.data);
if (!ret_data.status){
layer.msg(ret_data.msg,{icon:2,time:2000});
return;
}
if(typeof(callback) == 'function'){
callback(res);
}
},'json');
},
repeatPwd:function (a, id) {
$("#"+id).val(randomStrPwd(a))
},
save_cfg:function(version){
var username = $("input[name='username']").val();
var password = $("input[name='password']").val();
this.send({
tips:'正在设置中...',
data:{'username':username,'password':password},
method:'nezha_save_cfg',
success:function(rdata){
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
}
});
},
cfg:function(version){
this.send({
tips:'正在获取中...',
method:'nezha_cfg',
success:function(data){
var d = data.data;
var value = '<p>\
<span>用户名</span>\
<input id="nz_username" style="width: 160px;" class="bt-input-text mr5" name="username" value="'+d['username']+'" type="text">\
,<span title="随机用户名" class="glyphicon glyphicon-repeat cursor" onclick="nezha.repeatPwd(8,\'nz_username\')"></span>\
</p>';
value += '<p>\
<span>密码</span>\
<input id="nz_password" style="width: 160px;" class="bt-input-text mr5" name="password" value="'+d['password']+'" type="text">\
,<span title="随机密码" class="glyphicon glyphicon-repeat cursor" onclick="nezha.repeatPwd(16,\'nz_password\')"></span>\
</p>';
var conf = '<style>.conf_p p{margin-bottom: 2px;} .conf_p span {width: 50px;}</style><div class="conf_p" style="margin-bottom:0">\
' + value + '\
<div style="margin-top:10px; padding-right:15px" class="text-right">\
<button class="btn btn-success btn-sm mr5" onclick="nezha.cfg(\'' + version + '\')">刷新</button>\
<button class="btn btn-success btn-sm" onclick="nezha.save_cfg(\'' + version + '\')">保存</button>\
</div>\
</div>'
$(".soft-man-con").html(conf);
}
});
},
agent_save_cfg:function(version){
var host = $("input[name='host']").val();
var secret = $("input[name='secret']").val();
this.send({
tips:'正在设置中...',
data:{'host':host,'secret':secret},
method:'agent_save_cfg',
success:function(rdata){
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
}
});
},
agent_cfg:function(version){
this.send({
tips:'正在获取中...',
method:'agent_cfg',
success:function(data){
var d = data.data;
var value = '<p>\
<span>地址</span>\
<input id="nz_username" style="width: 160px;" class="bt-input-text mr5" name="host" value="'+d['host']+'" type="text">\
,<font>如1.1.1.1:5444</font>\
</p>';
value += '<p>\
<span>密钥</span>\
<input id="nz_password" style="width: 160px;" class="bt-input-text mr5" name="secret" value="'+d['secret']+'" type="text">\
,<font>密钥</font>\
</p>';
var conf = '<style>.conf_p p{margin-bottom: 2px;} .conf_p span {width: 50px;}</style><div class="conf_p" style="margin-bottom:0">\
' + value + '\
<div style="margin-top:10px; padding-right:15px" class="text-right">\
<button class="btn btn-success btn-sm mr5" onclick="nezha.agent_cfg(\'' + version + '\')">刷新</button>\
<button class="btn btn-success btn-sm" onclick="nezha.agent_save_cfg(\'' + version + '\')">保存</button>\
</div>\
</div>'
$(".soft-man-con").html(conf);
}
});
},
readme:function (){
var readme = '<ul class="help-info-text c7">';
readme += '<li>安装时不会自动启动。</li>';
readme += '<li>哪吒面板是改造版,用户名和密码登录【面板配置】,不依赖github/gitee/gitlab。</li>';
readme += '<li>Agent需要先手动填写正确信息。</li>';
readme += '</ul>';
$('.soft-man-con').html(readme);
}
}
+158
View File
@@ -0,0 +1,158 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=0.15.2
# bash install.sh install 0.15.2
# cd /www/server/mdserver-web/plugins/nezha && bash install.sh install 0.15.2
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/nezha && bash install.sh install 0.15.2
bash ${rootPath}/scripts/getos.sh
OSNAME=`cat ${rootPath}/data/osname.pl`
OSNAME_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
ARCH="amd64"
get_arch() {
TMP_ARCH=`arch`
if [ "$TMP_ARCH" == "x86_64" ];then
ARCH="amd64"
elif [ "$TMP_ARCH" == "aarch64" ];then
ARCH="arm64"
else
echo $ARCH
fi
}
load_vars() {
OS=$(uname | tr '[:upper:]' '[:lower:]')
TARGET_DIR="$serverPath/nezha/dashboard"
## China_IP
if [[ -z "${CN}" ]]; then
if [[ $(curl -m 10 -s https://ipapi.co/json | grep 'China') != "" ]]; then
CN=true
fi
fi
if [[ -z "${CN}" ]]; then
GITHUB_RAW_URL="raw.githubusercontent.com/midoks/nezha/main"
GITHUB_URL="github.com"
else
GITHUB_RAW_URL="cdn.jsdelivr.net/gh/midoks/nezha@main"
GITHUB_URL="dn-dao-github-mirror.daocloud.io"
fi
echo $GITHUB_RAW_URL
echo $GITHUB_URL
}
# download file
download_file() {
url="${1}"
destination="${2}"
printf "Fetching ${url} \n\n"
if test -x "$(command -v curl)"; then
code=$(curl --connect-timeout 15 -w '%{http_code}' -L "${url}" -o "${destination}")
elif test -x "$(command -v wget)"; then
code=$(wget -t2 -T15 -O "${destination}" --server-response "${url}" 2>&1 | awk '/^ HTTP/{print $2}' | tail -1)
else
printf "\e[1;31mNeither curl nor wget was available to perform http requests.\e[0m\n"
exit 1
fi
if [ "${code}" != 200 ]; then
printf "\e[1;31mRequest failed with code %s\e[0m\n" $code
exit 1
else
printf "\n\e[1;33mDownload succeeded\e[0m\n"
fi
}
Install_dashborad(){
echo '正在安装哪吒监控...' > $install_tmp
mkdir -p $serverPath/source
if [ ! -f $TARGET_DIR/nezha ];then
DOWNLOAD_URL="https://${GITHUB_URL}/midoks/nezha/releases/download/v${VERSION}/nezha-${OS}-${ARCH}.zip"
DOWNLOAD_FILE="$(mktemp).zip"
download_file $DOWNLOAD_URL $DOWNLOAD_FILE
if [ ! -d $TARGET_DIR ]; then
mkdir -p $TARGET_DIR
fi
unzip $DOWNLOAD_FILE -d $TARGET_DIR
rm -rf $DOWNLOAD_FILE
fi
}
Install_agent(){
echo -e "正在下载监控端" > $install_tmp
mkdir -p $serverPath/source
version=v0.15.1
AGENT_TARGET_DIR="$serverPath/nezha/agent"
DOWNLOAD_URL="https://${GITHUB_URL}/nezhahq/agent/releases/download/${version}/nezha-agent_${OS}_${ARCH}.zip"
DOWNLOAD_FILE="$(mktemp).zip"
if [ ! -f $AGENT_TARGET_DIR/nezha-agent ];then
download_file $DOWNLOAD_URL $DOWNLOAD_FILE
if [ ! -d $AGENT_TARGET_DIR ]; then
mkdir -p $AGENT_TARGET_DIR
fi
unzip $DOWNLOAD_FILE -d $AGENT_TARGET_DIR
rm -rf $DOWNLOAD_FILE
fi
}
Install_App()
{
load_vars
get_arch
Install_dashborad
Install_agent
if [ -d $serverPath/nezha ];then
echo "$VERSION" > $serverPath/nezha/version.pl
cd ${rootPath} && python3 ${rootPath}/plugins/nezha/index.py init_cfg
fi
echo 'install successful' > $install_tmp
}
Uninstall_App()
{
cd ${rootPath} && python3 ${rootPath}/plugins/nezha/index.py initd_uninstall
cd ${rootPath} && python3 ${rootPath}/plugins/nezha/index.py initd_uninstall_agent
cd ${rootPath} && python3 ${rootPath}/plugins/nezha/index.py stop
cd ${rootPath} && python3 ${rootPath}/plugins/nezha/index.py stop_agent
rm -rf $serverPath/nezha
echo "install fail" > $install_tmp
}
action=$1
if [ "${1}" == 'install' ];then
Install_App
else
Uninstall_App
fi
@@ -0,0 +1,2 @@
## 指定共享内存
lua_shared_dict healthcheck 10m;
@@ -0,0 +1,64 @@
location / {
proxy_pass http://{$UPSTREAM_NAME};
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $proxy_host;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
#location /upstream_status {
# allow 127.0.0.1;
# deny all;
# access_log off;
# default_type text/plain;
# content_by_lua_block {
# local hc = require "resty.upstream.healthcheck"
# ngx.say("OpenResty Worker PID: ", ngx.worker.pid())
# ngx.print(hc.status_page())
# }
#}
location /upstream_status_{$UPSTREAM_NAME} {
allow 127.0.0.1;
deny all;
access_log off;
default_type text/plain;
content_by_lua_block {
local json = require "cjson"
local ok, upstream = pcall(require, "ngx.upstream")
if not ok then
ngx.print("[]")
return
end
local get_primary_peers = upstream.get_primary_peers
local get_backup_peers = upstream.get_backup_peers
local upstream_name = "{$UPSTREAM_NAME}"
peers, err = get_primary_peers(upstream_name)
if not peers then
ngx.print("[]")
return
end
peers_backup, err = get_backup_peers(upstream_name)
if peers_backup then
for k, v in pairs(peers_backup) do
table.insert(peers,v)
end
end
ngx.print(json.encode(peers))
}
}
@@ -0,0 +1,5 @@
upstream {$UPSTREAM_NAME}
{
{$NODE_ALGO}
{$NODE_SERVER_LIST}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

+21
View File
@@ -0,0 +1,21 @@
<div class="bt-form">
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('op_load_balance');">服务</p>
<p onclick="loadBalanceList();">负载均衡</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<script type="text/javascript" src="/plugins/file?name=op_load_balance&f=js/app.js"></script>
<script type="text/javascript">
resetPluginWinWidth(800);
resetPluginWinHeight(300);
$.getScript( "/plugins/file?name=op_load_balance&f=js/app.js", function(){
pluginService('op_load_balance');
});
</script>
+474
View File
@@ -0,0 +1,474 @@
# coding:utf-8
import sys
import io
import os
import time
import subprocess
import json
import re
sys.path.append(os.getcwd() + "/class/core")
import mw
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getPluginName():
return 'op_load_balance'
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('}')
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 getConf():
path = getServerDir() + "/cfg.json"
if not os.path.exists(path):
mw.writeFile(path, '[]')
c = mw.readFile(path)
return json.loads(c)
def writeConf(data):
path = getServerDir() + "/cfg.json"
mw.writeFile(path, json.dumps(data))
def contentReplace(content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$APP_PATH}', app_path)
return content
def restartWeb():
mw.opWeb('stop')
mw.opWeb('start')
def loadBalanceConf():
path = mw.getServerDir() + '/web_conf/nginx/vhost/load_balance.conf'
return path
def initDreplace():
dst_conf_tpl = getPluginDir() + '/conf/load_balance.conf'
dst_conf = loadBalanceConf()
if not os.path.exists(dst_conf):
con = mw.readFile(dst_conf_tpl)
mw.writeFile(dst_conf, con)
def status():
if not mw.getWebStatus():
return 'stop'
dst_conf = loadBalanceConf()
if not os.path.exists(dst_conf):
return 'stop'
return 'start'
def start():
initDreplace()
restartWeb()
return 'ok'
def stop():
dst_conf = loadBalanceConf()
os.remove(dst_conf)
deleteLoadBalanceAllCfg()
restartWeb()
return 'ok'
def restart():
restartWeb()
return 'ok'
def reload():
restartWeb()
return 'ok'
def installPreInspection():
check_op = mw.getServerDir() + "/openresty"
if not os.path.exists(check_op):
return "请先安装OpenResty"
return 'ok'
def deleteLoadBalanceAllCfg():
cfg = getConf()
upstream_dir = mw.getServerDir() + '/web_conf/nginx/upstream'
lua_dir = mw.getServerDir() + '/web_conf/nginx/lua/init_worker_by_lua_file'
rewrite_dir = mw.getServerDir() + '/web_conf/nginx/rewrite'
vhost_dir = mw.getServerDir() + '/web_conf/nginx/vhost'
for conf in cfg:
upstream_file = upstream_dir + '/' + conf['upstream_name'] + '.conf'
if os.path.exists(upstream_file):
os.remove(upstream_file)
lua_file = lua_dir + '/' + conf['upstream_name'] + '.lua'
if os.path.exists(lua_file):
os.remove(lua_file)
rewrite_file = rewrite_dir + '/' + conf['domain'] + '.conf'
mw.writeFile(rewrite_file, '')
path = vhost_dir + '/' + conf['domain'] + '.conf'
content = mw.readFile(path)
content = re.sub('include ' + upstream_file + ';' + "\n", '', content)
mw.writeFile(path, content)
mw.opLuaInitWorkerFile()
def makeConfServerList(data):
slist = ''
for x in data:
slist += 'server '
slist += x['ip'] + ':' + x['port']
if x['state'] == '0':
slist += ' down;\n\t'
continue
if x['state'] == '2':
slist += ' backup;\n\t'
continue
slist += ' weight=' + x['weight']
slist += ' max_fails=' + x['max_fails']
slist += ' fail_timeout=' + x['fail_timeout'] + "s;\n\t"
return slist
def makeLoadBalanceAllCfg(row):
# 生成所有配置
cfg = getConf()
upstream_dir = mw.getServerDir() + '/web_conf/nginx/upstream'
rewrite_dir = mw.getServerDir() + '/web_conf/nginx/rewrite'
vhost_dir = mw.getServerDir() + '/web_conf/nginx/vhost'
upstream_tpl = getPluginDir() + '/conf/upstream.tpl.conf'
rewrite_tpl = getPluginDir() + '/conf/rewrite.tpl.conf'
if not os.path.exists(upstream_dir):
os.makedirs(upstream_dir)
conf = cfg[row]
# replace vhost start
vhost_file = vhost_dir + '/' + conf['domain'] + '.conf'
vcontent = mw.readFile(vhost_file)
vhost_find_str = 'upstream/' + conf['upstream_name'] + '.conf'
vhead = 'include ' + mw.getServerDir() + '/web_conf/nginx/' + \
vhost_find_str + ';'
vpos = vcontent.find(vhost_find_str)
if vpos < 0:
vcontent = vhead + "\n" + vcontent
mw.writeFile(vhost_file, vcontent)
# replace vhost end
# make upstream start
upstream_file = upstream_dir + '/' + conf['upstream_name'] + '.conf'
content = ''
if len(conf['node_list']) > 0:
content = mw.readFile(upstream_tpl)
slist = makeConfServerList(conf['node_list'])
content = content.replace('{$NODE_SERVER_LIST}', slist)
content = content.replace('{$UPSTREAM_NAME}', conf['upstream_name'])
if conf['node_algo'] != 'polling':
content = content.replace('{$NODE_ALGO}', conf['node_algo'] + ';')
else:
content = content.replace('{$NODE_ALGO}', '')
mw.writeFile(upstream_file, content)
# make upstream end
# make rewrite start
rewrite_file = rewrite_dir + '/' + conf['domain'] + '.conf'
rcontent = ''
if len(conf['node_list']) > 0:
rcontent = mw.readFile(rewrite_tpl)
rcontent = rcontent.replace('{$UPSTREAM_NAME}', conf['upstream_name'])
mw.writeFile(rewrite_file, rcontent)
# make rewrite end
# health check start
lua_dir = mw.getServerDir() + '/web_conf/nginx/lua/init_worker_by_lua_file'
lua_init_worker_file = lua_dir + '/' + conf['upstream_name'] + '.lua'
if conf['node_health_check'] == 'ok':
lua_dir_tpl = getPluginDir() + '/lua/health_check.lua.tpl'
content = mw.readFile(lua_dir_tpl)
content = content.replace('{$UPSTREAM_NAME}', conf['upstream_name'])
content = content.replace('{$DOMAIN}', conf['domain'])
mw.writeFile(lua_init_worker_file, content)
else:
if os.path.exists(lua_init_worker_file):
os.remove(lua_init_worker_file)
mw.opLuaInitWorkerFile()
# health check end
return True
def add_load_balance(args):
data = checkArgs(
args, ['domain', 'upstream_name', 'node_algo', 'node_list', 'node_health_check'])
if not data[0]:
return data[1]
domain_json = args['domain']
tmp = json.loads(domain_json)
domain = tmp['domain']
cfg = getConf()
cfg_len = len(cfg)
tmp = {}
tmp['domain'] = domain
tmp['data'] = args['domain']
tmp['upstream_name'] = args['upstream_name']
tmp['node_algo'] = args['node_algo']
tmp['node_list'] = args['node_list']
tmp['node_health_check'] = args['node_health_check']
cfg.append(tmp)
writeConf(cfg)
import site_api
sobj = site_api.site_api()
domain_path = mw.getWwwDir() + '/' + domain
ps = '负载均衡[' + domain + ']'
data = sobj.add(domain_json, '80', ps, domain_path, '00')
makeLoadBalanceAllCfg(cfg_len)
mw.restartWeb()
return mw.returnJson(True, '添加成功', data)
def edit_load_balance(args):
data = checkArgs(
args, ['row', 'node_algo', 'node_list', 'node_health_check'])
if not data[0]:
return data[1]
row = int(args['row'])
cfg = getConf()
tmp = cfg[row]
tmp['node_algo'] = args['node_algo']
tmp['node_list'] = args['node_list']
tmp['node_health_check'] = args['node_health_check']
cfg[row] = tmp
writeConf(cfg)
makeLoadBalanceAllCfg(row)
mw.restartWeb()
return mw.returnJson(True, '修改成功', data)
def loadBalanceList():
cfg = getConf()
return mw.returnJson(True, 'ok', cfg)
def loadBalanceDelete():
args = getArgs()
data = checkArgs(args, ['row'])
if not data[0]:
return data[1]
row = int(args['row'])
cfg = getConf()
data = cfg[row]
import site_api
sobj = site_api.site_api()
sid = mw.M('sites').where('name=?', (data['domain'],)).getField('id')
if type(sid) == list:
del(cfg[row])
writeConf(cfg)
return mw.returnJson(False, '已经删除了!')
status = sobj.delete(sid, data['domain'], 1)
status_data = json.loads(status)
if status_data['status']:
del(cfg[row])
writeConf(cfg)
upstream_dir = mw.getServerDir() + '/web_conf/nginx/upstream'
rewrite_dir = mw.getServerDir() + '/web_conf/nginx/rewrite'
upstream_file = upstream_dir + '/' + data['upstream_name'] + '.conf'
if os.path.exists(upstream_file):
os.remove(upstream_file)
rewrite_file = rewrite_dir + '/' + data['domain'] + '.conf'
if os.path.exists(rewrite_file):
mw.writeFile(rewrite_file, '')
return mw.returnJson(status_data['status'], status_data['msg'])
def http_get(url):
ret = re.search(r'https://', url)
if ret:
try:
from gevent import monkey
monkey.patch_ssl()
import requests
ret = requests.get(url=str(url), verify=False, timeout=10)
status = [200, 301, 302, 404, 403]
if ret.status_code in status:
return True
else:
return False
except:
return False
else:
try:
if sys.version_info[0] == 2:
import urllib2
rec = urllib2.urlopen(url, timeout=3)
else:
import urllib.request
rec = urllib.request.urlopen(url, timeout=3)
status = [200, 301, 302, 404, 403]
if rec.getcode() in status:
return True
return False
except:
return False
def checkUrl():
args = getArgs()
data = checkArgs(args, ['ip', 'port', 'path'])
if not data[0]:
return data[1]
ip = args['ip']
port = args['port']
path = args['path']
if port == '443':
url = 'https://' + str(ip) + ':' + str(port) + str(path.strip())
else:
url = 'http://' + str(ip) + ':' + str(port) + str(path.strip())
ret = http_get(url)
if not ret:
return mw.returnJson(False, '访问节点[%s]失败' % url)
return mw.returnJson(True, '访问节点[%s]成功' % url)
def getHealthStatus():
args = getArgs()
data = checkArgs(args, ['row'])
if not data[0]:
return data[1]
row = int(args['row'])
cfg = getConf()
data = cfg[row]
url = 'http://' + data['domain'] + \
'/upstream_status_' + data['upstream_name']
url_data = mw.httpGet(url)
return mw.returnJson(True, 'ok', json.loads(url_data))
def getLogs():
args = getArgs()
data = checkArgs(args, ['domain'])
if not data[0]:
return data[1]
domain = args['domain']
logs = mw.getLogsDir() + '/' + domain + '.log'
return logs
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 == 'install_pre_inspection':
print(installPreInspection())
elif func == 'add_load_balance':
print(addLoadBalance())
elif func == 'load_balance_list':
print(loadBalanceList())
elif func == 'load_balance_delete':
print(loadBalanceDelete())
elif func == 'check_url':
print(checkUrl())
elif func == 'get_logs':
print(getLogs())
elif func == 'get_health_status':
print(getHealthStatus())
else:
print('error')
+16
View File
@@ -0,0 +1,16 @@
{
"title":"OP负载均衡",
"tip":"soft",
"name":"op_load_balance",
"type":"其他插件",
"install_pre_inspection":true,
"ps":"基于OpenResty的负载均衡",
"shell":"install.sh",
"checks":"server/op_load_balance",
"path":"server/op_load_balance",
"author":"midoks",
"home":"https://github.com/midoks",
"date":"2023-02-02",
"pid": "1",
"versions": ["1.0"]
}
+45
View File
@@ -0,0 +1,45 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
action=$1
version=$2
sys_os=`uname`
if [ -f ${rootPath}/bin/activate ];then
source ${rootPath}/bin/activate
fi
if [ "$sys_os" == "Darwin" ];then
BAK='_bak'
else
BAK=''
fi
Install_App(){
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/op_load_balance
echo "${version}" > $serverPath/op_load_balance/version.pl
cd ${rootPath} && python3 ${rootPath}/plugins/op_load_balance/index.py start
echo 'install ok' > $install_tmp
}
Uninstall_App(){
cd ${rootPath} && python3 ${rootPath}/plugins/op_load_balance/index.py stop
rm -rf $serverPath/op_load_balance
}
action=$1
if [ "${1}" == 'install' ];then
Install_App
else
Uninstall_App
fi
+606
View File
@@ -0,0 +1,606 @@
function ooPost(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:'op_load_balance', 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 ooAsyncPost(method,args){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(toArrayObject(args));
} else {
_args = JSON.stringify(args);
}
return syncPost('/plugins/run', {name:'op_load_balance', func:method, args:_args});
}
function ooPostCallbak(method, args, callback){
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
var req_data = {};
req_data['name'] = 'op_load_balance';
req_data['func'] = method;
args['version'] = '1.0';
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 addNode(){
layer.open({
type: 1,
area: ['450px','580px'],
title: '添加节点',
closeBtn: 1,
shift: 5,
shadeClose: true,
btn:['提交','关闭'],
content: "<form class='bt-form pd20'>\
<div class='line'>\
<span class='tname'>IP地址</span>\
<div class='info-r'>\
<input name='ip' class='bt-input-text mr5' placeholder='负载名称,可以是英文字母和下划线,不能使用中文' type='text' style='width:250px' value='127.0.0.1'>\
</div>\
</div>\
<div class='line'>\
<span class='tname'>端口</span>\
<div class='info-r'>\
<input name='port' class='bt-input-text mr5' type='text' style='width:250px' value='80'>\
</div>\
</div>\
<div class='line'>\
<span class='tname'>验证文件路径</span>\
<div class='info-r'>\
<input name='path' class='bt-input-text mr5' type='text' style='width:250px' value='/'>\
</div>\
</div>\
<div class='line'>\
<span class='tname'>节点状态</span>\
<div class='info-r'>\
<select name='state'>\
<option value='1'>参与者</option>\
<option value='2'>备份</option>\
<option value='0'>停用</option>\
</select>\
</div>\
</div>\
<div class='line'>\
<span class='tname'>权重</span>\
<div class='info-r'>\
<input name='weight' class='bt-input-text mr5' type='text' style='width:250px' value='1'>\
</div>\
</div>\
<div class='line'>\
<span class='tname'>阈值</span>\
<div class='info-r'>\
<input name='max_fails' class='bt-input-text mr5' type='text' style='width:250px' value='2'>次\
</div>\
</div>\
<div class='line'>\
<span class='tname'>恢复时间</span>\
<div class='info-r'>\
<input name='fail_timeout' class='bt-input-text mr5' type='text' style='width:250px' value='10'>秒\
</div>\
</div>\
<ul style='margin-left:10px' class='help-info-text c7'>\
<li>备份状态: 指当其它节点都无法使用时才会使用此节点</li>\
<li>参与状态: 正常参与负载均衡,请至少添加1个普通节点</li>\
<li>验证文件路径: 用于检查文件路径地址是否可用</li>\
<li>IP地址: 仅支持IP地址,否则无法正常参与负载均衡</li>\
<li>阈值: 在恢复时间的时间段内,如果OpenResty与节点通信尝试失败的次数达到此值,OpenResty就认为服务器不可用</li>\
</ul>\
</form>",
success:function(){
},
yes:function(index) {
var ip = $('input[name="ip"]').val();
var port = $('input[name="port"]').val();
var path = $('input[name="path"]').val();
var state = $('select[name="state"]').val();
var weight = $('input[name="weight"]').val();
var max_fails = $('input[name="max_fails"]').val();
var fail_timeout = $('input[name="fail_timeout"]').val();
ooPost('check_url', {ip:ip,port:port,path:path},function(rdata){
var rdata = $.parseJSON(rdata.data);
showMsg(rdata.msg, function(){
if (rdata.status){
layer.close(index);
$('#nodecon .nulltr').hide();
var tbody = '<tr>';
tbody +='<td>'+ip+'</td>';
tbody +='<td>'+port+'</td>';
tbody +='<td>'+path+'</td>';
tbody +="<td><select name='state'>";
var state_option_list = {
'1':'参与者',
'2':'备份',
'0':'停用',
}
for (i in state_option_list) {
if (i == state){
tbody +="<option value='"+i+"' selected>"+state_option_list[i]+"</option>";
} else{
tbody +="<option value='"+i+"'>"+state_option_list[i]+"</option>";
}
}
tbody +="</select></td>";
tbody +='<td><input type="number" name="weight" value="'+weight+'" style="width:50px"></td>';
tbody +='<td><input type="number" name="max_fails" value="'+max_fails+'" style="width:50px"></td>';
tbody +='<td><input type="number" name="fail_timeout" value="'+fail_timeout+'" style="width:50px"></td>';
tbody +='<td class="text-right" width="50"><a class="btlink minus delete">删除</a></td>';
tbody += '</tr>';
$('#nodecon').append(tbody);
$('#nodecon .delete').click(function(){
$(this).parent().parent().remove();
if ($('#nodecon tr').length == 1 ){
$('#nodecon .nulltr').show();
}
});
}
},{ icon: rdata.status ? 1 : 2 }, 2000);
});
}
});
}
function addBalance(){
layer.open({
type: 1,
area: ['750px','460px'],
title: '创建负载',
closeBtn: 1,
shift: 5,
shadeClose: true,
btn:['提交','关闭'],
content: "<form class='bt-form pd20'>\
<div class='line'>\
<span class='tname'>域名</span>\
<div class='info-r'><textarea name='load_domain' class='bt-input-text mr5' placeholder='' style='width:95%;resize: none;height:90px;line-height:20px;'></textarea></div>\
</div>\
<div class='line'>\
<span class='tname'>负载名称</span>\
<div class='info-r'>\
<input name='upstream_name' class='bt-input-text mr5' placeholder='负载名称,可以是英文字母和下划线,不能使用中文' type='text' style='width:95%' value=''>\
</div>\
</div>\
<div class='line'>\
<span class='tname'>节点调度</span>\
<div class='info-r'>\
<select name='node_algo'>\
<option value='polling'>轮询[默认]</option>\
<option value='ip_hash'>ip_hash</option>\
<option value='fair'>fair</option>\
<option value='url_hash'>url_hash</option>\
<option value='least_conn'>least_conn</option>\
</select>\
</div>\
</div>\
<div class='line'>\
<span class='tname'>节点健康检查</span>\
<div class='info-r'>\
<input type='checkbox' name='node_health_check' checked>\
</div>\
</div>\
<div class='line'>\
<span class='tname'>节点</span>\
<div class='info-r'>\
<div class='table-con divtable' style='max-height:120px;overflow:auto; margin-bottom:8px;width:95%'>\
<table class='table table-hover' id='fixTable3'>\
<thead>\
<tr>\
<th width='120'>IP地址</th>\
<th width='60'>端口</th>\
<th width='120'>验证路径</th>\
<th width='60'>状态</th>\
<th width='60'>权重</th>\
<th width='60'>阀值</th>\
<th width='120'>恢复时间</th>\
<th width='80' class='text-right'>操作</th>\
</tr>\
</thead>\
<tbody id='nodecon'>\
<tr class='nulltr'>\
<td colspan='8' align='center'>当前节点为空,请至少添加一个普通节点</td>\
</tr>\
</tbody>\
</table>\
</div>\
<span class='btn btn-success btn-sm add_node' style='vertical-align:0'>添加节点</span>\
</div>\
</div>\
</form>",
success:function(){
$('textarea[name="load_domain"]').attr('placeholder','每行填写一个域名,默认为80端口。\n泛解析添加方法 *.domain.com\n如另加端口格式为 www.domain.com:88');
var rval = getRandomString(6);
$('input[name="upstream_name"]').val('load_balance_'+rval);
$('.add_node').click(function(){
addNode();
});
},
yes:function(index) {
var data = {};
var upstream_name = $('input[name="upstream_name"]').val();
if (upstream_name == ''){
layer.msg('负载名称不能为空!',{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
var domain = $('textarea[name="load_domain"]').val().replace('http://','').replace('https://','').split("\n");
if (domain[0] == ''){
layer.msg('域名不能为空!',{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
var domainlist = '';
for(var i=1; i<domain.length; i++){
domainlist += '"'+domain[i]+'",';
}
domain ='{"domain":"'+domain[0]+'","domainlist":['+domainlist+'],"count":'+domain.length+'}';//拼接json
data['domain'] = domain;
data['upstream_name'] = upstream_name;
data['node_algo'] = $('select[name="node_algo"]').val();
data['node_health_check'] = 'fail';
if ($('input[name="node_health_check"]').prop('checked')){
data['node_health_check'] = 'ok';
}
var node_list = [];
$('#nodecon tr').each(function(){
var ip = $(this).find('td').eq(0).text();
var port = $(this).find('td').eq(1).text();
if (port == ''){return;}
var path = $(this).find('td').eq(2).text();
var state = $(this).find('select[name="state"]').val();
var weight = $(this).find('input[name="weight"]').val();
var max_fails = $(this).find('input[name="max_fails"]').val();
var fail_timeout = $(this).find('input[name="fail_timeout"]').val();
var tmp = {
ip:ip,
port:port,
path:path,
state:state,
weight:weight,
max_fails:max_fails,
fail_timeout:fail_timeout,
}
node_list.push(tmp);
});
data['node_list'] = node_list;
ooPostCallbak('add_load_balance', data, function(rdata){
var rdata = $.parseJSON(rdata.data);
showMsg(rdata.msg, function(){
layer.close(index);
loadBalanceListRender();
},{ icon: rdata.status ? 1 : 2 }, 2000);
});
}
});
}
function editBalance(data, row){
layer.open({
type: 1,
area: ['750px','400px'],
title: '编辑负载',
closeBtn: 1,
shift: 5,
shadeClose: true,
btn:['提交','关闭'],
content: "<form class='bt-form pd20'>\
<div class='line'>\
<span class='tname'>负载名称</span>\
<div class='info-r'><input name='upstream_name' class='bt-input-text mr5' type='text' style='width:95%;background: rgb(238, 238, 238);' value='' readonly></div>\
</div>\
<div class='line'>\
<span class='tname'>节点调度</span>\
<div class='info-r'>\
<select name='node_algo'>\
<option value='polling'>轮询[默认]</option>\
<option value='ip_hash'>ip_hash</option>\
<option value='fair'>fair</option>\
<option value='url_hash'>url_hash</option>\
<option value='least_conn'>least_conn</option>\
</select>\
</div>\
</div>\
<div class='line'>\
<span class='tname'>节点健康检查</span>\
<div class='info-r'>\
<input type='checkbox' name='node_health_check'>\
</div>\
</div>\
<div class='line'>\
<span class='tname'>节点</span>\
<div class='info-r'>\
<div class='table-con divtable' style='max-height:120px;overflow:auto; margin-bottom:8px;width:95%'>\
<table class='table table-hover' id='fixTable3'>\
<thead>\
<tr>\
<th width='120'>IP地址</th>\
<th width='60'>端口</th>\
<th width='120'>验证路径</th>\
<th width='60'>状态</th>\
<th width='60'>权重</th>\
<th width='60'>阀值</th>\
<th width='120'>恢复时间</th>\
<th width='80' class='text-right'>操作</th>\
</tr>\
</thead>\
<tbody id='nodecon'>\
<tr class='nulltr'>\
<td colspan='8' align='center'>当前节点为空,请至少添加一个普通节点</td>\
</tr>\
</tbody>\
</table>\
</div>\
<span class='btn btn-success btn-sm add_node' style='vertical-align:0'>添加节点</span>\
</div>\
</div>\
</form>",
success:function(){
$('input[name="upstream_name"]').val(data['upstream_name']);
$('select[name="node_algo"]').val(data['node_algo']);
$('input[name="node_health_check"]').prop('checked',false);
if (data['node_health_check'] == 'ok'){
$('input[name="node_health_check"]').prop('checked',true);
}
var node_list = data['node_list'];
if (node_list.length>0){
$('#nodecon .nulltr').hide();
}
var state_option_list = {
'1':'参与者',
'2':'备份',
'0':'停用',
}
for (var n in node_list) {
var tbody = '<tr>';
tbody +='<td>'+node_list[n]['ip']+'</td>';
tbody +='<td>'+node_list[n]['port']+'</td>';
tbody +='<td>'+node_list[n]['path']+'</td>';
tbody +="<td><select name='state'>";
for (i in state_option_list) {
if (i == node_list[n]['state']){
tbody +="<option value='"+i+"' selected>"+state_option_list[i]+"</option>";
} else{
tbody +="<option value='"+i+"'>"+state_option_list[i]+"</option>";
}
}
tbody +="</select></td>";
tbody +='<td><input type="number" name="weight" value="'+node_list[n]['weight']+'" style="width:50px"></td>';
tbody +='<td><input type="number" name="max_fails" value="'+node_list[n]['max_fails']+'" style="width:50px"></td>';
tbody +='<td><input type="number" name="fail_timeout" value="'+node_list[n]['fail_timeout']+'" style="width:50px"></td>';
tbody +='<td class="text-right" width="50"><a class="btlink minus delete">删除</a></td>';
tbody += '</tr>';
$('#nodecon').append(tbody);
}
$('#nodecon .delete').click(function(){
$(this).parent().parent().remove();
if ($('#nodecon tr').length == 1 ){
$('#nodecon .nulltr').show();
}
});
$('.add_node').click(function(){
addNode();
});
},
yes:function(index) {
var data = {};
data['node_algo'] = $('select[name="node_algo"]').val();
data['node_health_check'] = 'fail';
if ($('input[name="node_health_check"]').prop('checked')){
data['node_health_check'] = 'ok';
}
var node_list = [];
$('#nodecon tr').each(function(){
var ip = $(this).find('td').eq(0).text();
var port = $(this).find('td').eq(1).text();
if (port == ''){return;}
var path = $(this).find('td').eq(2).text();
var state = $(this).find('select[name="state"]').val();
var weight = $(this).find('input[name="weight"]').val();
var max_fails = $(this).find('input[name="max_fails"]').val();
var fail_timeout = $(this).find('input[name="fail_timeout"]').val();
var tmp = {
ip:ip,
port:port,
path:path,
state:state,
weight:weight,
max_fails:max_fails,
fail_timeout:fail_timeout,
}
node_list.push(tmp);
});
data['node_list'] = node_list;
data['row'] = row;
ooPostCallbak('edit_load_balance', data, function(rdata){
var rdata = $.parseJSON(rdata.data);
showMsg(rdata.msg, function(){
layer.close(index);
loadBalanceListRender();
},{ icon: rdata.status ? 1 : 2 }, 2000);
});
}
});
}
function loadBalanceListRender(){
ooPost('load_balance_list', {}, function(rdata){
var rdata = $.parseJSON(rdata.data);
var alist = rdata.data;
var tbody = '';
for (var i = 0; i < alist.length; i++) {
tbody += '<tr>';
tbody += '<td>'+alist[i]['domain']+'</td>';
tbody += '<td>'+alist[i]['upstream_name']+'</td>';
tbody += '<td>'+alist[i]['node_list'].length+'</td>';
tbody += '<td><a class="btlink log_look" data-row="'+i+'">查看</a></td>';
tbody += '<td><a class="btlink health_status" data-row="'+i+'">查看</a></td>';
tbody += '<td style="text-align: right;"><a class="btlink edit" data-row="'+i+'">修改</a> | <a class="btlink delete" data-row="'+i+'">删除</a></td>';
tbody += '</tr>';
}
$('#nodeTable').html(tbody);
$('.nodeTablePage .Pcount').text('共'+alist.length+'条');
$('#nodeTable .edit').click(function(){
var row = $(this).data('row');
editBalance(alist[row],row);
});
$('#nodeTable .log_look').click(function(){
var row = $(this).data('row');
var args = {'domain':alist[row]['domain']};
pluginRollingLogs('op_load_balance','','get_logs',JSON.stringify(args),20);
});
$('#nodeTable .health_status').click(function(){
var row = $(this).data('row');
ooPost('get_health_status', {row:row}, function(rdata){
var rdata = $.parseJSON(rdata.data);
var tval = '';
for (var i = 0; i < rdata.data.length; i++) {
tval += '<tr>';
tval += '<td>'+rdata.data[i]['name']+'</td>';
if (typeof(rdata.data[i]['down']) != 'undefined' && rdata.data[i]['down']){
tval += '<td><span style="color:red;">不正常</span></td>';
} else{
tval += '<td><span class="btlink">正常</span></td>';
}
tval += '</tr>';
}
var tbody = "<div class='bt-form pd20'>\
<div>\
<div id='gitea_table' class='divtable' style='margin-top:5px;'>\
<table class='table table-hover'>\
<thead>\
<tr>\
<th width='120'>地址</th>\
<th width='60'>状态</th>\
</tr>\
</thead>\
<tbody>"+tval+"</tbody>\
</table>\
</div>\
</div>\
</div>";
layer.open({
type: 1,
area: ['500px','300px'],
title: '节点状态',
closeBtn: 1,
shift: 5,
shadeClose: true,
btn:['提交','关闭'],
content:tbody,
});
});
});
$('#nodeTable .delete').click(function(){
var row = $(this).data('row');
ooPost('load_balance_delete', {row:row}, function(rdata){
var rdata = $.parseJSON(rdata.data);
showMsg(rdata.msg, function(){
loadBalanceListRender();
},{ icon: rdata.status ? 1 : 2 }, 2000);
});
});
});
}
function loadBalanceList() {
var body = '<div class="bt-box active" style="display: block;">\
<div class="mb10">\
<button class="btn btn-success btn-sm" data-index="0" onclick="addBalance()">添加负载</button>\
<div class="divtable mt10">\
<table class="table table-hover">\
<thead>\
<tr>\
<th>网站</th>\
<th>负载名称</th>\
<th>节点</th>\
<th>日志</th>\
<th>状态</th>\
<th width="100" style="text-align: right;">操作</th>\
</tr>\
</thead>\
<tbody id="nodeTable"></tbody>\
</table>\
<div class="nodeTablePage page" data-type="nodePage">\
<div><span class="Pcount">共0条</span></div>\
</div>\
</div>\
</div>\
</div>\
</div>';
$(".soft-man-con").html(body);
loadBalanceListRender();
}
@@ -0,0 +1,18 @@
local hc = require "resty.upstream.healthcheck"
local ok, err = hc.spawn_checker {
shm = "healthcheck",
type = "http",
upstream = "{$UPSTREAM_NAME}",
http_req = "GET / HTTP/1.0\r\nHost: {$UPSTREAM_NAME}\r\n\r\n",
interval = 2000,
timeout = 6000,
fall = 3,
rise = 2,
valid_statuses = {200, 302},
concurrency = 20,
}
if not ok then
ngx.log(ngx.ERR, "=======> load balance health checker error: ", err)
return
end
+43 -41
View File
@@ -533,49 +533,51 @@ end
function waf()
min_route()
-- C:D("min_route")
-- white ip
if waf_ip_white() then return true end
-- C:D("waf_ip_white")
-- url white
if waf_url_white() then return true end
-- C:D("waf_url_white")
-- black ip
if waf_ip_black() then return true end
-- C:D("waf_ip_black")
-- 封禁ip返回
if waf_drop_ip() then return true end
-- C:D("waf_drop_ip")
-- ua check
if waf_user_agent() then return true end
-- C:D("waf_user_agent")
if waf_url() then return true end
-- C:D("waf_url")
-- cc setting
if waf_cc_increase() then return true end
-- C:D("waf_cc_increase")
if waf_cc() then return true end
-- C:D("waf_cc")
-- cookie检查
if waf_cookie() then return true end
-- C:D("waf_cookie")
-- args参数拦截
if waf_get_args() then return true end
-- C:D("waf_get_args")
-- 扫描软件禁止
if waf_scan_black() then return true end
-- C:D("waf_scan_black")
if waf_post() then return true end
-- C:D("waf_post")
if site_config[server_name] and site_config[server_name]['open'] then
-- white ip
if waf_ip_white() then return true end
-- C:D("waf_ip_white")
-- url white
if waf_url_white() then return true end
-- C:D("waf_url_white")
-- black ip
if waf_ip_black() then return true end
-- C:D("waf_ip_black")
-- 封禁ip返回
if waf_drop_ip() then return true end
-- C:D("waf_drop_ip")
-- ua check
if waf_user_agent() then return true end
-- C:D("waf_user_agent")
if waf_url() then return true end
-- C:D("waf_url")
-- cc setting
if waf_cc_increase() then return true end
-- C:D("waf_cc_increase")
if waf_cc() then return true end
-- C:D("waf_cc")
-- cookie检查
if waf_cookie() then return true end
-- C:D("waf_cookie")
-- args参数拦截
if waf_get_args() then return true end
-- C:D("waf_get_args")
-- 扫描软件禁止
if waf_scan_black() then return true end
-- C:D("waf_scan_black")
if waf_post() then return true end
-- C:D("waf_post")
--------------------------------------------------------
--------------------------------------------------------
if X_Forwarded() then return true end
-- C:D("X_Forwarded")
if post_X_Forwarded() then return true end
+19 -12
View File
@@ -60,19 +60,26 @@ http
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server_tokens off;
access_log off;
# CACEH_BEGIN
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 512 4k;
proxy_busy_buffers_size 64k;
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;
proxy_read_timeout 5s;
proxy_send_timeout 5s;
server {
listen 80;
listen [::]:80;
server_name 127.0.0.1;
allow 127.0.0.1;
location /nginx_status {
stub_status on;
access_log off;
}
}
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_path {$SERVER_PATH}/openresty/nginx/fastcgi_cache_temp levels=1:2 keys_zone=mw_cache_fcgi:100m inactive=60m max_size=5g;
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
# CACEH_END
server_tokens off;
access_log /dev/null;
include {$SERVER_PATH}/web_conf/nginx/vhost/*.conf;
}
@@ -0,0 +1,10 @@
server {
listen 80;
listen [::]:80;
server_name 127.0.0.1;
allow 127.0.0.1;
location /nginx_status {
stub_status on;
access_log off;
}
}
@@ -0,0 +1,4 @@
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
+12
View File
@@ -180,6 +180,17 @@ def confReplace():
cmd_s = 'chmod u+s ' + ng_exe_bin
os.system('echo %s|sudo -S %s' % (sudoPwd, cmd_s))
# vhost
vhost_dir = mw.getServerDir() + '/web_conf/nginx/vhost'
vhost_tpl_dir = getPluginDir() + '/conf/vhost'
# print(vhost_dir, vhost_tpl_dir)
vhost_list = ['0.websocket.conf', '0.nginx_status.conf']
for f in vhost_list:
a_conf = vhost_dir + '/' + f
a_conf_tpl = vhost_tpl_dir + '/' + f
if not os.path.exists(a_conf):
mw.writeFile(a_conf, mw.readFile(a_conf_tpl))
def initDreplace():
@@ -290,6 +301,7 @@ def restart():
def reload():
confReplace()
return restyOp('reload')
+2 -2
View File
@@ -12,6 +12,6 @@
"home":"http://openresty.org",
"date":"2017-11-24",
"pid": "1",
"versions": ["1.17.8.2","1.19.3.1","1.21.4.1"],
"updates": ["1.17.8.2","1.19.3.1","1.21.4.1"]
"versions": ["1.17.8.2","1.19.3.1","1.21.4.2"],
"updates": ["1.17.8.2","1.19.3.1","1.21.4.2"]
}
+12 -1
View File
@@ -61,7 +61,18 @@ Install_openresty()
# wget -O openresty-1.21.4.1.tar.gz https://openresty.org/download/openresty-1.21.4.1.tar.gz
if [ ! -f ${openrestyDir}/openresty-${VERSION}.tar.gz ];then
wget -O ${openrestyDir}/openresty-${VERSION}.tar.gz https://openresty.org/download/openresty-${VERSION}.tar.gz
wget --no-check-certificate -O ${openrestyDir}/openresty-${VERSION}.tar.gz https://openresty.org/download/openresty-${VERSION}.tar.gz -T 3
fi
DOWNLOAD_SIZE=`wc -c ${openrestyDir}/openresty-${VERSION}.tar.gz | awk '{print $1}'`
if [ "$DOWNLOAD_SIZE" == "0" ];then
echo 'download failed, download again'
rm -rf ${openrestyDir}/openresty-${VERSION}.tar.gz
fi
# Last Download Method
if [ ! -f ${openrestyDir}/openresty-${VERSION}.tar.gz ];then
wget --no-check-certificate -O ${openrestyDir}/openresty-${VERSION}.tar.gz https://dl.midoks.me/soft/openresty/openresty-${VERSION}.tar.gz -T 3
fi
cd ${openrestyDir} && tar -zxvf openresty-${VERSION}.tar.gz
+1 -1
View File
@@ -658,7 +658,7 @@ function phpLibConfig(version){
//安装扩展
function installPHPLib(version, name, title, pathinfo) {
layer.confirm('您真的要安装{1}吗?'.replace('{1}', name), { icon: 3, closeBtn: 2 }, function() {
layer.confirm('您真的要卸载{1}吗?'.replace('{1}', name), { icon: 3, closeBtn: 2 }, function() {
name = name.toLowerCase();
var data = "name=" + name + "&version=" + version + "&type=1";
+1 -1
View File
@@ -672,7 +672,7 @@ function installPHPLib(version, name, title, pathinfo) {
//卸载扩展
function uninstallPHPLib(version, name, title, pathinfo) {
layer.confirm('您真的要安装{1}吗?'.replace('{1}', name), { icon: 3, closeBtn: 2 }, function() {
layer.confirm('您真的要卸载{1}吗?'.replace('{1}', name), { icon: 3, closeBtn: 2 }, function() {
name = name.toLowerCase();
var data = 'name=' + name + '&version=' + version;
phpPost('uninstall_lib', version, data, function(data){
+2 -2
View File
@@ -12,9 +12,9 @@ version=$1
action=$2
if [ -f /lib/systemd/system/php${version}-php-fpm.service ];then
systemctl ${action} php${version}
systemctl ${action} php${version}-php-fpm
elif [[ -f /usr/lib/systemd/system/php${version}-php-fpm.service ]]; then
systemctl ${action} php${version}
systemctl ${action} php${version}-php-fpm
else
$serverPath/php/init.d/php${version} ${action}
fi
+1
View File
@@ -7,6 +7,7 @@ Description=The PHP {$VERSION} FastCGI Process Manager
After=network.target
[Service]
Environment="LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/www/server/lib/icu/lib"
PIDFile={$SERVER_PATH}/php/{$VERSION}/var/run/php-fpm.pid
ExecStart={$SERVER_PATH}/php/{$VERSION}/sbin/php-fpm --nodaemonize --fpm-config {$SERVER_PATH}/php/{$VERSION}/etc/php-fpm.conf
ExecReload=/bin/kill -USR2 $MAINPID
+2 -1
View File
@@ -49,6 +49,7 @@ fi
cd ${curPath} && sh -x $curPath/versions/$2/install.sh $1
if [ "${action}" == "install" ] && [ -d ${serverPath}/php/${type} ];then
#初始化
@@ -59,6 +60,7 @@ if [ "${action}" == "install" ] && [ -d ${serverPath}/php/${type} ];then
echo "install PHP${type} extend start"
# cd /www/server/mdserver-web/plugins/php/versions/common && bash iconv.sh install 53
# cd /www/server/mdserver-web/plugins/php/versions/common && bash intl.sh install 73
# cd /www/server/mdserver-web/plugins/php/versions/common && bash gd.sh install 56
# cd /www/server/mdserver-web/plugins/php/versions/common && bash openssl.sh install 56
# cd /www/server/mdserver-web/plugins/php/versions/common && bash sodium.sh install 81
@@ -72,7 +74,6 @@ if [ "${action}" == "install" ] && [ -d ${serverPath}/php/${type} ];then
cd ${rootPath}/plugins/php/versions/common && bash gettext.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash redis.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash memcached.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash zlib.sh install ${type}
if [ "${type}" -gt "72" ];then
cd ${rootPath}/plugins/php/versions/common && bash zip.sh install ${type}
+1 -1
View File
@@ -665,7 +665,7 @@ function installPHPLib(version, name, title, pathinfo) {
//卸载扩展
function uninstallPHPLib(version, name, title, pathinfo) {
layer.confirm('您真的要安装{1}吗?'.replace('{1}', name), { icon: 3, closeBtn: 2 }, function() {
layer.confirm('您真的要卸载{1}吗?'.replace('{1}', name), { icon: 3, closeBtn: 2 }, function() {
name = name.toLowerCase();
var data = 'name=' + name + '&version=' + version;
phpPost('uninstall_lib', version, data, function(data){
+14 -5
View File
@@ -15,11 +15,20 @@ SOURCE_ROOT=$rootPath/source/lib
if [ ! -d ${SERVER_ROOT}/freetype ];then
cd $SOURCE_ROOT
wget -O freetype-2.12.1.tar.gz --no-check-certificate https://download.savannah.gnu.org/releases/freetype/freetype-2.12.1.tar.gz -T 5
tar zxvf freetype-2.12.1.tar.gz
cd freetype-2.12.1
if [ ! -f $SOURCE_ROOT/freetype-2.12.1.tar.gz ];then
wget -O freetype-2.12.1.tar.gz --no-check-certificate https://download.savannah.gnu.org/releases/freetype/freetype-2.12.1.tar.gz -T 5
fi
if [ ! -d $SOURCE_ROOT/freetype-2.12.1 ];then
tar zxvf freetype-2.12.1.tar.gz
cd freetype-2.12.1
else
cd freetype-2.12.1
fi
./configure --prefix=${SERVER_ROOT}/freetype && make && make install
cd $SOURCE_ROOT
cd $SOURCE_ROOT && rm -rf freetype-2.12.1
#rm -rf freetype-2.12.1.tar.gz
#rm -rf freetype-2.12.1
fi
+14 -5
View File
@@ -15,11 +15,20 @@ SOURCE_ROOT=$rootPath/source/lib
if [ ! -d ${SERVER_ROOT}/freetype_old ];then
cd $SOURCE_ROOT
wget -O freetype-2.7.1.tar.gz --no-check-certificate https://download.savannah.gnu.org/releases/freetype/freetype-2.7.1.tar.gz -T 5
tar zxvf freetype-2.7.1.tar.gz
cd freetype-2.7.1
if [ ! -f $SOURCE_ROOT/freetype-2.7.1.tar.gz ];then
wget -O freetype-2.7.1.tar.gz --no-check-certificate https://download.savannah.gnu.org/releases/freetype/freetype-2.7.1.tar.gz -T 5
fi
if [ ! -d $SOURCE_ROOT/freetype-2.7.1 ];then
tar zxvf freetype-2.7.1.tar.gz
cd freetype-2.7.1
else
cd freetype-2.7.1
fi
./configure --prefix=${SERVER_ROOT}/freetype_old && make && make install
#cd $SOURCE_ROOT
cd $SOURCE_ROOT && rm -rf freetype-2.7.1
#rm -rf freetype-2.7.1.tar.gz
#rm -rf freetype-2.7.1
fi
+16
View File
@@ -24,6 +24,22 @@ mkdir -p $serverPath/php
cd ${rootPath}/plugins/php/lib && /bin/bash zlib.sh
if [ ! -d $sourcePath/php/php${PHP_VER} ];then
# ----------------------------------------------------------------------- #
# 中国优化安装
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
LOCAL_ADDR=common
if [ ! -z "$cn" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "cn" ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://mirrors.sohu.com/php/php-${version}.tar.xz
fi
fi
# ----------------------------------------------------------------------- #
if [ ! -f $sourcePath/php/php-${version}.tar.gz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.gz https://museum.php.net/php5/php-${version}.tar.gz
fi
+16
View File
@@ -24,6 +24,22 @@ mkdir -p $serverPath/php
cd ${rootPath}/plugins/php/lib && /bin/bash zlib.sh
if [ ! -d $sourcePath/php/php${PHP_VER} ];then
# ----------------------------------------------------------------------- #
# 中国优化安装
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
LOCAL_ADDR=common
if [ ! -z "$cn" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "cn" ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://mirrors.sohu.com/php/php-${version}.tar.xz
fi
fi
# ----------------------------------------------------------------------- #
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://museum.php.net/php5/php-${version}.tar.xz
fi
+16
View File
@@ -24,6 +24,22 @@ mkdir -p $serverPath/php
cd ${rootPath}/plugins/php/lib && /bin/bash zlib.sh
if [ ! -d $sourcePath/php/php${PHP_VER} ];then
# ----------------------------------------------------------------------- #
# 中国优化安装
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
LOCAL_ADDR=common
if [ ! -z "$cn" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "cn" ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://mirrors.sohu.com/php/php-${version}.tar.xz
fi
fi
# ----------------------------------------------------------------------- #
if [ ! -f $sourcePath/php/php-${version}.tar.gz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.gz https://museum.php.net/php5/php-${version}.tar.gz
fi
+16
View File
@@ -23,6 +23,22 @@ cd ${rootPath}/plugins/php/lib && /bin/bash freetype_old.sh
cd ${rootPath}/plugins/php/lib && /bin/bash zlib.sh
if [ ! -d $sourcePath/php/php${PHP_VER} ];then
# ----------------------------------------------------------------------- #
# 中国优化安装
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
LOCAL_ADDR=common
if [ ! -z "$cn" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "cn" ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://mirrors.sohu.com/php/php-${version}.tar.xz
fi
fi
# ----------------------------------------------------------------------- #
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://museum.php.net/php5/php-${version}.tar.xz
fi
+16
View File
@@ -23,6 +23,22 @@ cd ${rootPath}/plugins/php/lib && /bin/bash freetype_old.sh
cd ${rootPath}/plugins/php/lib && /bin/bash zlib.sh
if [ ! -d $sourcePath/php/php${PHP_VER} ];then
# ----------------------------------------------------------------------- #
# 中国优化安装
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
LOCAL_ADDR=common
if [ ! -z "$cn" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "cn" ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://mirrors.sohu.com/php/php-${version}.tar.xz
fi
fi
# ----------------------------------------------------------------------- #
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://museum.php.net/php5/php-${version}.tar.xz
fi
+16
View File
@@ -23,6 +23,22 @@ cd ${rootPath}/plugins/php/lib && /bin/bash freetype_old.sh
cd ${rootPath}/plugins/php/lib && /bin/bash zlib.sh
if [ ! -d $sourcePath/php/php${PHP_VER} ];then
# ----------------------------------------------------------------------- #
# 中国优化安装
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
LOCAL_ADDR=common
if [ ! -z "$cn" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "cn" ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://mirrors.sohu.com/php/php-${version}.tar.xz
fi
fi
# ----------------------------------------------------------------------- #
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://museum.php.net/php7/php-${version}.tar.xz
fi
+16
View File
@@ -23,6 +23,22 @@ cd ${rootPath}/plugins/php/lib && /bin/bash freetype_old.sh
cd ${rootPath}/plugins/php/lib && /bin/bash zlib.sh
if [ ! -d $sourcePath/php/php${PHP_VER} ];then
# ----------------------------------------------------------------------- #
# 中国优化安装
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
LOCAL_ADDR=common
if [ ! -z "$cn" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "cn" ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://mirrors.sohu.com/php/php-${version}.tar.xz
fi
fi
# ----------------------------------------------------------------------- #
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://museum.php.net/php7/php-${version}.tar.xz
fi
+16
View File
@@ -24,6 +24,22 @@ cd ${rootPath}/plugins/php/lib && /bin/bash freetype_old.sh
cd ${rootPath}/plugins/php/lib && /bin/bash zlib.sh
if [ ! -d $sourcePath/php/php${PHP_VER} ];then
# ----------------------------------------------------------------------- #
# 中国优化安装
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
LOCAL_ADDR=common
if [ ! -z "$cn" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "cn" ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://mirrors.sohu.com/php/php-${version}.tar.xz
fi
fi
# ----------------------------------------------------------------------- #
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://museum.php.net/php7/php-${version}.tar.xz
fi
+15
View File
@@ -28,6 +28,21 @@ cd ${rootPath}/plugins/php/lib && /bin/bash freetype_old.sh
cd ${rootPath}/plugins/php/lib && /bin/bash zlib.sh
if [ ! -d $sourcePath/php/php${PHP_VER} ];then
# ----------------------------------------------------------------------- #
# 中国优化安装
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
LOCAL_ADDR=common
if [ ! -z "$cn" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "cn" ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://mirrors.sohu.com/php/php-${version}.tar.xz
fi
fi
# ----------------------------------------------------------------------- #
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://museum.php.net/php7/php-${version}.tar.xz
+21 -1
View File
@@ -10,7 +10,6 @@ sourcePath=${serverPath}/source
sysName=`uname`
install_tmp=${rootPath}/tmp/mw_install.pl
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"; }
@@ -29,8 +28,29 @@ cd ${rootPath}/plugins/php/lib && /bin/bash freetype_new.sh
cd ${rootPath}/plugins/php/lib && /bin/bash zlib.sh
cd ${rootPath}/plugins/php/lib && /bin/bash libzip.sh
# redat ge 8
which yum
if [ "$?" == "0" ];then
cd ${rootPath}/plugins/php/lib && /bin/bash oniguruma.sh
fi
if [ ! -d $sourcePath/php/php${PHP_VER} ];then
# ----------------------------------------------------------------------- #
# 中国优化安装
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
LOCAL_ADDR=common
if [ ! -z "$cn" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "cn" ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://mirrors.sohu.com/php/php-${version}.tar.xz
fi
fi
# ----------------------------------------------------------------------- #
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://museum.php.net/php7/php-${version}.tar.xz
fi
+23 -1
View File
@@ -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.0.27
version=8.0.29
PHP_VER=80
Install_php()
{
@@ -28,7 +28,29 @@ mkdir -p $serverPath/php
cd ${rootPath}/plugins/php/lib && /bin/bash freetype_new.sh
cd ${rootPath}/plugins/php/lib && /bin/bash zlib.sh
# redat ge 8
which yum
if [ "$?" == "0" ];then
cd ${rootPath}/plugins/php/lib && /bin/bash oniguruma.sh
fi
if [ ! -d $sourcePath/php/php${PHP_VER} ];then
# ----------------------------------------------------------------------- #
# 中国优化安装
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
LOCAL_ADDR=common
if [ ! -z "$cn" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "cn" ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://mirrors.sohu.com/php/php-${version}.tar.xz
fi
fi
# ----------------------------------------------------------------------- #
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://www.php.net/distributions/php-${version}.tar.xz
+22 -1
View File
@@ -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.1.15
version=8.1.20
PHP_VER=81
Install_php()
{
@@ -28,9 +28,30 @@ mkdir -p $serverPath/php
cd ${rootPath}/plugins/php/lib && /bin/bash freetype_new.sh
cd ${rootPath}/plugins/php/lib && /bin/bash zlib.sh
# redat ge 8
which yum
if [ "$?" == "0" ];then
cd ${rootPath}/plugins/php/lib && /bin/bash oniguruma.sh
fi
if [ ! -d $sourcePath/php/php${PHP_VER} ];then
# ----------------------------------------------------------------------- #
# 中国优化安装
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
LOCAL_ADDR=common
if [ ! -z "$cn" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "cn" ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://mirrors.sohu.com/php/php-${version}.tar.xz
fi
fi
# ----------------------------------------------------------------------- #
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://www.php.net/distributions/php-${version}.tar.xz
fi
+22 -1
View File
@@ -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.2
version=8.2.7
PHP_VER=82
Install_php()
{
@@ -28,9 +28,30 @@ mkdir -p $serverPath/php
cd ${rootPath}/plugins/php/lib && /bin/bash freetype_new.sh
cd ${rootPath}/plugins/php/lib && /bin/bash zlib.sh
# redat ge 8
which yum
if [ "$?" == "0" ];then
cd ${rootPath}/plugins/php/lib && /bin/bash oniguruma.sh
fi
if [ ! -d $sourcePath/php/php${PHP_VER} ];then
# ----------------------------------------------------------------------- #
# 中国优化安装
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
LOCAL_ADDR=common
if [ ! -z "$cn" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "cn" ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://mirrors.sohu.com/php/php-${version}.tar.xz
fi
fi
# ----------------------------------------------------------------------- #
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://www.php.net/distributions/php-${version}.tar.xz
fi
+2 -1
View File
@@ -38,9 +38,10 @@ done
cd $DIR
PHP_VER_LIST=(53 54 55 56 70 71 72 73 74 80 81 82)
# yar
PHP_EXT_LIST=(ioncube ZendGuardLoader pdo mysqlnd sqlite3 openssl pcntl opcache mcrypt fileinfo \
exif gd intl memcache memcached redis imagemagick xdebug xhprof \
swoole yaf yar yac apc mongo mongodb solr seaslog mbstring iconv phalcon)
swoole yaf yac apc mongo mongodb solr seaslog mbstring iconv phalcon)
for PHP_VER in ${PHP_VER_LIST[@]}; do
echo "php${PHP_VER} -- start"
+31 -1
View File
@@ -11,9 +11,37 @@ rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sourcePath=${serverPath}/source/php
# _os=`uname`
# if [ ${_os} == "Darwin" ]; then
# OSNAME='macos'
# elif grep -Eq "openSUSE" /etc/*-release; then
# OSNAME='opensuse'
# elif grep -Eq "FreeBSD" /etc/*-release; then
# OSNAME='freebsd'
# elif grep -Eqi "CentOS" /etc/issue || grep -Eqi "CentOS" /etc/*-release; then
# OSNAME='rhel'
# elif grep -Eqi "Fedora" /etc/issue || grep -Eqi "Fedora" /etc/*-release; then
# OSNAME='rhel'
# elif grep -Eqi "Rocky" /etc/issue || grep -Eqi "Rocky" /etc/*-release; then
# OSNAME='rhel'
# elif grep -Eqi "AlmaLinux" /etc/issue || grep -Eqi "AlmaLinux" /etc/*-release; then
# OSNAME='rhel'
# elif grep -Eqi "Amazon Linux" /etc/issue || grep -Eqi "Amazon Linux" /etc/*-release; then
# OSNAME='amazon'
# elif grep -Eqi "Debian" /etc/issue || grep -Eqi "Debian" /etc/*-release; then
# OSNAME='debian'
# elif grep -Eqi "Ubuntu" /etc/issue || grep -Eqi "Ubuntu" /etc/*-release; then
# OSNAME='ubuntu'
# else
# OSNAME='unknow'
# fi
actionType=$1
version=$2
LIBNAME=intl
LIBV=0
@@ -33,7 +61,9 @@ else
fi
OPTIONS=''
if [ "$version" -lt "71" ];then
if [ "$version" -lt "74" ];then
# cd /www/server/mdserver-web/plugins/php/lib && /bin/bash icu.sh
cd ${rootPath}/plugins/php/lib && /bin/bash icu.sh
OPTIONS="--with-icu-dir=${serverPath}/lib/icu"
fi
+1 -1
View File
@@ -23,7 +23,7 @@ if [ "$version" -lt "73" ];then
fi
if [ "$version" -gt "74" ];then
LIBV=5.1.2
LIBV=5.2.1
fi
LIB_PATH_NAME=lib/php
+5
View File
@@ -32,6 +32,11 @@ if [ "$version" -eq "72" ] || [ "$version" -eq "73" ];then
fi
if [ "$version" -gt "74" ];then
LIBV=3.3.5
fi
LIB_PATH_NAME=lib/php
if [ -d $serverPath/php/${version}/lib64 ];then
LIB_PATH_NAME=lib64
+8 -7
View File
@@ -51,10 +51,11 @@ Install_pureftp()
# https://github.com/jedisct1/pure-ftpd/releases/download/1.0.49/pure-ftpd-1.0.49.tar.gz
# https://download.pureftpd.org/pub/pure-ftpd/releases/pure-ftpd-1.0.49.tar.gz
# DOWNLOAD=https://github.com/jedisct1/pure-ftpd/releases/download/${VER}/pure-ftpd-${VER}.tar.gz
VER=$1
DOWNLOAD=https://download.pureftpd.org/pub/pure-ftpd/releases/pure-ftpd-${VER}.tar.gz
DOWNLOAD=https://github.com/jedisct1/pure-ftpd/releases/download/${VER}/pure-ftpd-${VER}.tar.gz
# DOWNLOAD=https://download.pureftpd.org/pub/pure-ftpd/releases/pure-ftpd-${VER}.tar.gz
# curl -sSLo pure-ftpd-1.0.49.tar.gz https://download.pureftpd.org/pub/pure-ftpd/releases/pure-ftpd-1.0.49.tar.gz
if [ ! -f $serverPath/source/pureftp/pure-ftpd-${VER}.tar.gz ];then
@@ -68,14 +69,14 @@ Install_pureftp()
md5_check=`md5sum $serverPath/source/pureftp/pure-ftpd-${VER}.tar.gz | awk '{print $1}'`
if [ "${md5_ok}" == "${md5_check}" ]; then
echo "pure-ftpd file check ok"
else
# 重新下载
rm -rf $serverPath/source/pureftp/pure-ftpd-${VER}
wget --no-check-certificate -O $serverPath/source/pureftp/pure-ftpd-${VER}.tar.gz $DOWNLOAD
# curl -sSLo $serverPath/source/pureftp/pure-ftpd-${VER}.tar.gz $DOWNLOAD
fi
fi
# Last Download Method
if [ ! -f $serverPath/source/pureftp/pure-ftpd-${VER}.tar.gz ];then
wget --no-check-certificate -O $serverPath/source/pureftp/pure-ftpd-${VER}.tar.gz https://dl.midoks.me/soft/ftp/pure-ftpd-${VER}.tar.gz -T 3
fi
if [ ! -d $serverPath/source/pureftp/pure-ftpd-${VER} ];then
cd $serverPath/source/pureftp && tar zxvf pure-ftpd-${VER}.tar.gz
fi
+11 -11
View File
@@ -782,20 +782,20 @@ def lsyncdAdd():
info['rsync'] = rsync
if not 'exclude' in info:
info["exclude"] = [
"/**.upload.tmp",
"**/*.log",
"**/*.tmp",
"**/*.temp",
".git",
".gitignore",
".user.ini",
]
data = getDefaultConf()
slist = data['send']["list"]
res = lsyncdListFindName(slist, info['name'])
if not 'exclude' in info:
if res[0]:
info["exclude"] = slist[res[1]]['exclude']
else:
info["exclude"] = [
"/**.upload.tmp", "**/*.log", "**/*.tmp",
"**/*.temp", ".git", ".gitignore", ".user.ini",
]
if res[0]:
list_index = res[1]
slist[list_index] = info
+4 -4
View File
@@ -476,7 +476,7 @@ function lsyncdExclude(name){
}
function lsyncdConfLog(){
pluginStandAloneLogs("rsyncd","","lsyncd_conf_log");;
pluginRollingLogs("rsyncd","","lsyncd_conf_log");;
}
function lsyncdSend(){
@@ -492,7 +492,7 @@ function lsyncdSend(){
con += '<div style="padding-top:1px;">\
<button class="btn btn-success btn-sm" onclick="createSendTask();">创建发送任务</button>\
<button class="btn btn-success btn-sm" onclick="lsyncdConfLog();">日志</button>\
<button class="btn btn-success btn-sm" onclick="lsyncdConfLog();">自动同步日志</button>\
</div>';
con += '<div class="divtable" style="margin-top:5px;"><table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">';
@@ -532,7 +532,7 @@ function lsyncdSend(){
'<td>' + period +'</td>' +
'<td>\
<a class="btlink" onclick="lsyncdRun(\''+list[i]['name']+'\')">同步</a>\
| <a class="btlink" onclick="lsyncdLog(\''+list[i]['name']+'\')">日志</a>\
| <a class="btlink" onclick="lsyncdLog(\''+list[i]['name']+'\')">手动日志</a>\
| <a class="btlink" onclick="lsyncdExclude(\''+list[i]['name']+'\')">过滤器</a>\
| <a class="btlink" onclick="createSendTask(\''+list[i]['name']+'\')">编辑</a>\
| <a class="btlink" onclick="lsyncdDelete(\''+list[i]['name']+'\')">删除</a>\
@@ -562,7 +562,7 @@ function rsyncdConf(){
}
function rsyncdLog(){
pluginStandAloneLogs("rsyncd","","run_log");
pluginRollingLogs("rsyncd","","run_log");
}
+162
View File
@@ -0,0 +1,162 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
+73
View File
@@ -0,0 +1,73 @@
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.
+960
View File
@@ -0,0 +1,960 @@
{
"open": false,
"service": {
"open": true,
"name": "服务加固",
"ps": "保护系统服务,开启后将无法添加和删除服务,部分软件无法安装!",
"paths": [
{
"path": "/etc/rc.d",
"chattr": "i",
"s_mode": 509,
"d_mode": 509
},
{
"path": "/etc/rc.d/init.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc.d/rc0.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc.d/rc1.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc.d/rc2.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc.d/rc3.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc.d/rc4.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc.d/rc5.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc.d/rc6.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc.d/rc.local",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/init.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc0.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc1.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc2.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc3.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc4.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc5.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rc6.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/rcS.d",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/etc/systemd",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
},
{
"path": "/lib/systemd",
"chattr": "i",
"s_mode": 493,
"d_mode": 493
}
]
},
"home": {
"open": true,
"name": "环境变量加固",
"ps": "保护用户环境变量不被修改,开启后无法自定义用户环境变量!",
"paths": [
{
"path": "/root/.bash_history",
"chattr": "a",
"s_mode": 420,
"d_mode": 420
},
{
"path": "/root/.bashrc",
"chattr": "i",
"s_mode": 420,
"d_mode": 420
},
{
"path": "/root/.bash_logout",
"chattr": "i",
"s_mode": 420,
"d_mode": 420
},
{
"path": "/root/.bash_profile",
"chattr": "i",
"s_mode": 420,
"d_mode": 420
},
{
"path": "/root/.profile",
"chattr": "i",
"s_mode": 420,
"d_mode": 420
},
{
"path": "/etc/profile",
"chattr": "i",
"s_mode": 420,
"d_mode": 420
},
{
"path": "/etc/bash.bashrc",
"chattr": "i",
"s_mode": 420,
"d_mode": 420
},
{
"path": "/etc/sysctl.conf",
"chattr": "i",
"s_mode": 420,
"d_mode": 420
},
{
"path": "/etc/sysctl.d",
"chattr": "i",
"s_mode": 420,
"d_mode": 420
}
]
},
"user": {
"open": true,
"name": "用户加固",
"ps": "保护用户,开启后将无法添加删除用户和修改用户密码!",
"paths": [
{
"path": "/etc/passwd",
"chattr": "i",
"s_mode": 420,
"d_mode": 420
},
{
"path": "/etc/group",
"chattr": "i",
"s_mode": 420,
"d_mode": 420
},
{
"path": "/usr/sbin/groupadd",
"chattr": "i",
"s_mode": 488,
"d_mode": 420
},
{
"path": "/usr/sbin/useradd",
"chattr": "i",
"s_mode": 488,
"d_mode": 420
},
{
"path": "/usr/bin/passwd",
"chattr": "i",
"s_mode": 509,
"d_mode": 420
}
]
},
"bin": {
"open": true,
"name": "关键目录加固",
"ps": "保护系统关键文件不被修改替换!",
"paths": [
{
"path": "/usr/bin",
"chattr": "i",
"s_mode": 365,
"d_mode": 365
},
{
"path": "/usr/sbin",
"chattr": "i",
"s_mode": 365,
"d_mode": 365
},
{
"path": "/etc/bashrc",
"chattr": "i",
"s_mode": 420,
"d_mode": 420
},
{
"path": "/usr/local/bin",
"chattr": "i",
"s_mode": 365,
"d_mode": 365
},
{
"path": "/usr/local/sbin",
"chattr": "i",
"s_mode": 365,
"d_mode": 365
},
{
"path": "/sbin",
"chattr": "i",
"s_mode": 365,
"d_mode": 365
},
{
"path": "/bin",
"chattr": "i",
"s_mode": 365,
"d_mode": 365
}
]
},
"cron": {
"open": true,
"name": "计划任务加固",
"ps": "保护计划任务不被篡改,开启后无法添加删除计划任务!",
"paths": [
{
"path": "/usr/bin/crontab",
"chattr": "i",
"s_mode": 509,
"d_mode": 420
},
{
"path": "/etc/crontab",
"chattr": "i",
"s_mode": 420,
"d_mode": 420
},
{
"path": "/etc/cron.d",
"chattr": "i",
"s_mode": 509,
"d_mode": 509
},
{
"path": "/etc/cron.daily",
"chattr": "i",
"s_mode": 509,
"d_mode": 420
},
{
"path": "/etc/cron.hourly",
"chattr": "i",
"s_mode": 509,
"d_mode": 420
},
{
"path": "/etc/cron.monthly",
"chattr": "i",
"s_mode": 509,
"d_mode": 420
},
{
"path": "/etc/cron.weekly",
"chattr": "i",
"s_mode": 509,
"d_mode": 420
},
{
"path": "/etc/anacrontab",
"chattr": "i",
"s_mode": 384,
"d_mode": 384
},
{
"path": "/var/spool/cron",
"chattr": "i",
"s_mode": 448,
"d_mode": 448
},
{
"path": "/var/spool/cron/root",
"chattr": "i",
"s_mode": 384,
"d_mode": 384
},
{
"path": "/var/spool/anacron",
"chattr": "i",
"s_mode": 509,
"d_mode": 509
}
]
},
"ssh": {
"open": true,
"name": "SSH服务加固",
"ps": "保护SSH不被暴力破解,记录用户登录日志",
"cycle": 120,
"limit": 3600,
"limit_count": 3
},
"process": {
"open": true,
"name": "异常进程监控",
"ps": "监控服务器进程列表,发现异常的进程后立即结束",
"process_white": [
"pip",
"pip3",
"yum",
"apt-get",
"apt",
"redis-cli",
"memcached",
"sshd",
"vm",
"vim",
"htop",
"top",
"sh",
"bash",
"zip",
"gzip",
"rsync",
"tar",
"unzip",
"rar",
"unrar",
"php",
"composer",
"pkill",
"mongo",
"mongod",
"php-fpm",
"php-fpm5.6",
"php-fpm7.0",
"php-fpm7.1",
"php-fpm7.2",
"php-fpm7.3",
"php-fpm7.4",
"php-fpm8.1",
"php-fpm8.2",
"nginx",
"httpd",
"lsof",
"ps",
"vi",
"vim",
"redis-server",
"mysqld",
"mysqld_safe",
"mysql",
"pure-ftpd",
"sparse_dd",
"stunnel",
"squeezed",
"vncterm",
"awk",
"ruby",
"postgres",
"mpathalert",
"vncterm",
"multipathd",
"fe",
"elasticsyslog",
"syslogd",
"v6d",
"xapi",
"screen",
"runsvdir",
"svlogd",
"java",
"udevd",
"ntpd",
"irqbalance",
"qmgr",
"wpa_supplicant",
"mysqld_safe",
"sftp-server",
"lvmetad",
"gitlab-web",
"pure-ftpd",
"auditd",
"master",
"dbus-daemon",
"tapdisk",
"init",
"ksoftirqd",
"kworker",
"kmpathd",
"kmpath_handlerd",
"python",
"kdmflush",
"bioset",
"crond",
"kthreadd",
"migration",
"rcu_sched",
"kjournald",
"gcc",
"gcc++",
"nginx",
"mysqld",
"php-cgi",
"login",
"firewalld",
"iptables",
"systemd",
"network",
"dhclient",
"systemd-journald",
"chrony",
"chronyd",
"chronyc",
"NetworkManager",
"systemd-logind",
"systemd-udevd",
"polkitd",
"tuned",
"rsyslogd",
"AliYunDunUpdate",
"AliYunDun",
"du",
"sendmail",
"gunicorn",
"python2",
"python3",
"python34",
"python2.6",
"runsv",
"dd",
"mkfs",
"fdisk",
"systemd-resolve",
"rpm",
"cc1",
"cc1plus",
"as",
"acme.sh",
"cc",
"du",
"grep",
"awk",
"sed",
"cut",
"free",
"df",
"firewall-cmd",
"ufw",
"echo",
"ls",
"cp",
"mv",
"rm",
"diff",
"ln",
"cat",
"more",
"wtmp",
"date",
"e2fsck",
"gunzip",
"ifconfig",
"ip",
"route",
"ping",
"scp",
"telnet",
"cd",
"comm",
"touch",
"man",
"w",
"who",
"last",
"clock",
"uname",
"su",
"uptime",
"vmstat",
"mount",
"umount",
"mkdir",
"mkswap",
"swapon",
"e2fsck",
"tune2fs",
"groupadd",
"useradd",
"passwd",
"userdel",
"chown",
"chmod",
"chgrp",
"id",
"mail",
"gzip",
"bzip2",
"bunzip2",
"networking",
"ssh",
"find",
"locate",
"slocate",
"dir",
"vdir",
"pwd",
"rename",
"rmdir",
"updatedb",
"whereis",
"which",
"compress",
"ar",
"arj",
"gzexe",
"bzip2",
"cksum",
"cmp",
"col",
"colrm",
"csplit",
"diff3",
"emacs",
"join",
"head",
"sort",
"wc",
"uniq",
"tail",
"sum",
"ulimit",
"pkill",
"kill",
"killall",
"pidof",
"pstree",
"watch",
"pgrep",
"dumpe2fs",
"mke2fs",
"sync",
"lsyncd",
"tune2fs",
"basename",
"file",
"locate/slocate",
"ls/dir/vdir",
"bzcat",
"bzip2recover",
"bzless/bzmore",
"cpio",
"dump",
"lha",
"resotre",
"unarj",
"uncompress",
"zcat",
"zforce",
"zipinfo",
"znew",
"diffstat",
"ed",
"ex",
"expand",
"fmt",
"fold",
"grep/egrep/fgrep",
"ispell",
"jed",
"joe",
"less",
"look",
"od",
"paste",
"pico",
"spell",
"split",
"tac",
"tee",
"tr",
"unexpand",
"alias",
"bg",
"bind",
"declare",
"dirs",
"enable",
"eval",
"exec",
"exit",
"export",
"fc",
"fg",
"hash",
"history",
"jobs",
"logout",
"popd",
"pushd",
"set",
"shopt",
"umask",
"unalias",
"unset",
"accept",
"cancel",
"disable",
"lp",
"lpadmin",
"lpc",
"lpq",
"lpr",
"lprm",
"lpstat",
"pr",
"reject",
"bc",
"cal",
"clear",
"consoletype",
"ctrlaltdel",
"dircolors",
"eject",
"halt",
"hostid",
"hwclock",
"info",
"md5sum",
"letsencrypt",
"mandb",
"mesg",
"mtools",
"mtoolstest",
"poweroff",
"reboot",
"shutdown",
"sleep",
"stat",
"talk",
"wall",
"whatis",
"whoami",
"write",
"cmsgoagent.linu",
"yes",
"chfn",
"chsh",
"finger",
"gpasswd",
"groupdel",
"groupmod",
"groups",
"grpck",
"grpconv",
"grpunconv",
"logname",
"pwck",
"pwconv",
"dd",
"mariadbd",
"pwunconv",
"usermod",
"users",
"nice",
"nohup",
"renice",
"badblocks",
"blockdev",
"chattr",
"convertquota",
"e2image",
"e2label",
"edquota",
"fail2ban-server",
"findfs",
"fsck",
"grub",
"hdparm",
"lilo",
"lsattr",
"mkbootdisk",
"mkinitrd",
"mkisofs",
"mknod",
"mktemp",
"parted",
"quota",
"quotacheck",
"xargs",
"bcm-agent",
"bcm-si",
"quotaoff",
"quotaon",
"quotastat",
"repquota",
"swapoff",
"depmod",
"dmesg",
"insmod",
"iostat",
"ipcs",
"kernelversion",
"lsmod",
"modinfo",
"modprobe",
"mpstat",
"rmmod",
"sar",
"slabtop",
"sysctl",
"tload",
"startx",
"xauth",
"xhost",
"xinit",
"xlsatoms",
"xlsclients",
"xlsfonts",
"xset",
"chroot",
"nmap",
"ntfs-3g",
"sftp",
"slogin",
"sudo",
"awk/gawk",
"expr",
"gdb",
"ldd",
"make",
"nm",
"perl",
"test",
"arch",
"at",
"atq",
"atrm",
"batch",
"chkconfig",
"crontab",
"lastb",
"logrotate",
"logsave",
"logwatch",
"lsusb",
"patch",
"runlevel",
"service",
"telinit",
"dnsdomainname",
"domainname",
"hostname",
"ifcfg",
"ifdown",
"ifup",
"stmpd",
"nisdomainname",
"ypdomainname",
"arp",
"arping",
"arpwatch",
"dig",
"elinks",
"elm",
"ftp",
"host",
"ipcalc",
"lynx",
"ncftp",
"netstat",
"nslookup",
"pine",
"dhclient-script",
"rsh",
"tftp",
"tracepath",
"traceroute",
"wget",
"arptables",
"iptables-save",
"iptables-restore",
"tcpdump",
"ab",
"apachectl",
"exportfs",
"htdigest",
"htpasswd",
"mailq",
"mysqladmin",
"msqldump",
"mysqlimport",
"mysqlshow",
"nfsstat",
"showmount",
"smbclient",
"smbmount",
"smbpasswd",
"squid",
"pickup",
"local",
"localedef",
"bounce",
"smtp",
"smtpd",
"trivial-rewrite",
"xe-daemon",
"cleanup",
"nm-dispatcher",
"lsinitrd",
"barad_agent",
"stop.sh",
"YDService",
"agetty",
"systemctl",
"AliSecureCheckA",
"containerd",
"containerd-shim",
"certbot-auto",
"oneav",
"oneavd",
"oneav_service_m",
"s3fs",
"bosfs",
"cosfs",
"flock",
"raidcheck",
"run-parts",
"man-db.cron",
"YDLive",
"sgagent"
],
"process_white_rule": [
"vif",
"node",
"pm2",
"npm",
"yarn",
"qemu",
"scsi_eh",
"xcp",
"xen",
"docker",
"yunsuo",
"scsi",
"jbd2",
"ext4",
"xfs",
"aliyun",
"kswapd",
"PM2",
"yunsuo",
"mkfs",
"Ali",
"watchdog",
"kworker",
"ksoftirqd",
"migration",
"mysql",
"/www/server/",
"cmsgoagent",
"python",
"python3",
"ifdown",
"node",
"sd-pam"
],
"process_exclude": [
"php-fpm",
"git",
"mysqld",
"mongod",
"dockerd",
"docker-containerd",
"memcached",
"jsvc",
"jsvc.exec",
"nginx",
"node",
"pm2",
"npm",
"yarn",
"httpd",
"gunicorn",
"configure",
"make",
"curl",
"wget",
"anacron",
"mysqldump",
"node",
"php",
"mysql",
"netstat",
"redis",
"postfix"
]
}
}

Some files were not shown because too many files have changed in this diff Show More