Compare commits

..
286 Commits
Author SHA1 Message Date
Mr Chen 9d9b39dfe2 Merge pull request #387 from midoks/dev
0.13.1
2023-02-28 19:11:06 +08:00
midoks 422514c40a 0.13.1
* 关闭issue,建立bbs.midoks.me。问题集中处理,发挥群众的力量。
* 添加站操作回调钩子site_cb。 网站统计和OP防火墙不再手动重载配置
* 修复ubuntu20 pureftp 安装时,端口没有加入安全里
* 增加global_static hook关键字,并优化menu的文件加载hook
* 各种细节优化。
2023-02-28 19:09:54 +08:00
midoks 632568643b Update site_api.py 2023-02-28 17:08:26 +08:00
midoks a5f29a2a6a Update cert_api.py 2023-02-28 16:26:31 +08:00
midoks b02705aa5a up 2023-02-28 03:00:46 +08:00
midoks 1f9ab560e3 Update files.js 2023-02-28 02:18:39 +08:00
midoks b3970326cd Update index.py 2023-02-28 01:57:19 +08:00
midoks f6d008e0b6 Update index.py 2023-02-28 01:50:54 +08:00
midoks 6f9a49ad7a up 2023-02-28 01:48:51 +08:00
midoks fc3c7d334a Update public.js 2023-02-28 00:17:39 +08:00
midoks 1030d1b923 site_cb 添加站操作回调钩子。 网站统计和OP防火墙不再手动重载配置 2023-02-28 00:02:16 +08:00
midoks 94d4a90bcc Update webstats_common.lua 2023-02-27 19:35:52 +08:00
midoks da4b872666 Update README.md 2023-02-27 17:57:17 +08:00
midoks cf15b19f4b Update install.sh 2023-02-26 21:46:25 +08:00
midoks aa9cdaada4 Update commit.tpl 2023-02-26 03:16:45 +08:00
midoks 659c9fe16b 修复ubuntu 20 pureftp 安装时,端口没有加入安全里 2023-02-26 02:20:06 +08:00
midoks 2b8c6d6e43 Update firewall_api.py 2023-02-26 01:39:52 +08:00
midoks 263f83088f Update firewall_api.py 2023-02-26 01:38:55 +08:00
midoks 374c938ac0 Update firewall_api.py 2023-02-26 01:38:32 +08:00
midoks 6aa73b0cae Update firewall_api.py 2023-02-26 01:36:45 +08:00
midoks 7f731ae06f Update README.md 2023-02-26 01:12:08 +08:00
midoks f87aff704c Update rhel.sh 2023-02-25 23:36:14 +08:00
midoks be9fa87133 Update rhel.sh 2023-02-25 23:31:36 +08:00
midoks de6fc19dee Create discuz.conf 2023-02-25 21:33:50 +08:00
midoks 3987c6d3dc Update config_api.py 2023-02-25 08:37:26 +08:00
midoks 96875052cd Update index.py 2023-02-25 08:25:05 +08:00
midoks 583de57f96 Update plugins_api.py 2023-02-25 08:21:20 +08:00
midoks 41b7245f03 Update plugins_api.py 2023-02-25 08:15:38 +08:00
midoks ee3684706f Update info.json 2023-02-25 07:48:32 +08:00
midoks 07936dfb81 update 2023-02-25 07:35:46 +08:00
midoks 5c46202be0 增加global_static hook关键字,并优化menu的文件加载hook
"hook":[
		{
			"tag":"global_static",
			"global_static": {
				"css_path":"menu/own_style.css",
				"js_path":"js/own_style.js"
			}
		}
	],
2023-02-25 07:26:48 +08:00
midoks 7123a15457 Update install.sh 2023-02-24 18:08:46 +08:00
midoks 4aeb45b1d5 Update install.sh 2023-02-24 17:55:13 +08:00
midoks 006a62be22 Update lib.sh 2023-02-24 17:25:04 +08:00
midoks 1e91d11125 Update mw.tpl 2023-02-24 17:22:22 +08:00
midoks 99fb4aa723 up 2023-02-24 17:14:28 +08:00
midoks 5c5bbb2da2 up 2023-02-24 17:12:31 +08:00
midoks 8b05045901 Update install.sh 2023-02-24 17:07:24 +08:00
midoks 1b73439525 Update install_dev.sh 2023-02-24 17:00:10 +08:00
midoks ec51ad016a Update install_dev.sh 2023-02-24 16:57:24 +08:00
midoks a42fae66ac Update install_dev.sh 2023-02-24 16:53:48 +08:00
midoks b4c635c2e5 Update install_dev.sh 2023-02-24 16:49:03 +08:00
midoks 9802bc5915 Update pure-ftpd.conf 2023-02-24 13:29:16 +08:00
Mr Chen 196fbbdd7d Merge pull request #382 from midoks/dev
0.13.0
2023-02-24 05:59:59 +08:00
midoks fa278abd50 Update index.py 2023-02-24 05:53:33 +08:00
midoks f9b2dbcb5e Update index.py 2023-02-24 05:46:39 +08:00
midoks a8808be9ae Update index.py 2023-02-24 05:41:50 +08:00
midoks 4122de13e3 Update index.py 2023-02-24 05:39:52 +08:00
midoks 4acae8e5f5 up 2023-02-24 05:38:59 +08:00
midoks 1abb611c3e 版本更新 0.13.0 2023-02-24 05:17:44 +08:00
midoks 726f9fa0d2 #374 2023-02-24 04:15:23 +08:00
midoks cfb64caadc Update site_api.py 2023-02-24 04:09:50 +08:00
midoks f501dd5150 Update site_api.py 2023-02-24 04:07:19 +08:00
midoks d1fe006e39 Update site_api.py 2023-02-24 03:28:48 +08:00
midoks d4db5dbfac up 2023-02-24 03:28:18 +08:00
midoks efa512a3f6 #374 2023-02-24 03:16:52 +08:00
midoks b53436343d up 2023-02-24 02:40:09 +08:00
midoks bb1a634f3c Update site_api.py 2023-02-24 02:29:14 +08:00
midoks acda55cc55 Update index.py 2023-02-24 01:40:02 +08:00
midoks 0ff0728517 Update index.py 2023-02-24 01:30:17 +08:00
midoks c575f55354 Update app.js 2023-02-24 01:05:32 +08:00
midoks d58339dbcb Update index.py 2023-02-24 00:07:19 +08:00
midoks f6a18fa25f Update index.py 2023-02-24 00:03:48 +08:00
midoks 3016eff372 Update app.js 2023-02-23 17:29:38 +08:00
midoks ca518591f3 up 2023-02-23 17:27:15 +08:00
midoks d2c74f2243 up 2023-02-23 17:17:46 +08:00
midoks 71dbf8e359 Update app.js 2023-02-23 15:39:16 +08:00
midoks cb2ad0ca82 up 2023-02-23 15:18:44 +08:00
midoks a157db7879 Update index.py 2023-02-23 03:32:30 +08:00
midoks fb949f4ee6 up 2023-02-23 01:25:00 +08:00
midoks b91ae3fde2 Update index.py 2023-02-22 23:46:28 +08:00
midoks b508e8003b Update index.py 2023-02-22 23:13:44 +08:00
midoks 0632a4b535 Update index.py 2023-02-22 23:13:17 +08:00
midoks 397e0b89a5 Update index.py 2023-02-22 22:59:45 +08:00
midoks 2427bf81cd Update index.py 2023-02-22 22:44:16 +08:00
midoks 4179bbf580 Update index.py 2023-02-22 22:40:29 +08:00
midoks b93c3bb88e Update index.py 2023-02-22 22:37:19 +08:00
midoks a52c854afd Update index.py 2023-02-22 22:36:10 +08:00
midoks d7e5cf1f45 Update index.py 2023-02-22 21:55:49 +08:00
midoks cfb444deac Update files_api.py 2023-02-22 20:54:54 +08:00
midoks 78615451ac up 2023-02-22 20:52:12 +08:00
midoks 0134643c83 Update db.py 2023-02-22 18:18:40 +08:00
midoks 70ddd1c86f Update index.py 2023-02-22 17:55:17 +08:00
midoks 808dc743ef Update files_api.py 2023-02-22 14:59:40 +08:00
midoks e30693f9f2 Update files_api.py 2023-02-22 14:28:01 +08:00
midoks 5c97fbe011 Update __init__.py 2023-02-22 14:27:48 +08:00
midoks 6419a18525 up 2023-02-21 21:10:34 +08:00
midoks 4a804e9243 Update index.py 2023-02-19 18:12:08 +08:00
midoks d44526004f up 2023-02-19 18:02:26 +08:00
midoks c1f402b278 up 2023-02-19 00:10:06 +08:00
midoks 45a3eec1b5 Update install_dev.sh 2023-02-18 23:09:51 +08:00
midoks d6f41ceb6a Update install_dev.sh 2023-02-18 23:06:53 +08:00
midoks a1bc0f6faf Update install_dev.sh 2023-02-18 22:58:21 +08:00
midoks 8420961cf7 Update install_dev.sh 2023-02-18 22:54:58 +08:00
midoks 421594c01d Update install_dev.sh 2023-02-18 22:48:30 +08:00
midoks ca13e8ad77 Update install_dev.sh 2023-02-18 22:46:05 +08:00
midoks f161f24253 up 2023-02-18 22:44:42 +08:00
midoks e5ab03951f Update README.md 2023-02-18 22:08:13 +08:00
midoks 5b45bab36d Update install_dev.sh 2023-02-18 22:06:51 +08:00
midoks 0594d3f9ce Update README.md 2023-02-18 22:04:11 +08:00
midoks ad541216c5 up 2023-02-18 16:59:33 +08:00
midoks 1adc0c1405 Update rhel.sh 2023-02-18 15:35:16 +08:00
midoks b22185b374 Update rhel.sh 2023-02-18 14:09:02 +08:00
midoks 02f3107e93 Update app.js 2023-02-18 02:04:52 +08:00
midoks 52fece867d up 2023-02-18 01:49:20 +08:00
midoks 2e3578dcf1 up 2023-02-18 01:39:26 +08:00
midoks 73b09a7886 up 2023-02-17 22:39:49 +08:00
midoks f33c7e5a5e up 2023-02-17 19:57:03 +08:00
midoks 3e90db2c8d Update system_api.py 2023-02-17 19:54:44 +08:00
midoks d599363609 Update index.py 2023-02-17 16:30:32 +08:00
midoks ec3167f239 Update __init__.py 2023-02-17 16:30:25 +08:00
midoks 2b1099b6e9 Update __init__.py 2023-02-17 15:42:28 +08:00
midoks e55a0760e3 Update mw.tpl 2023-02-17 15:22:15 +08:00
midoks 5c1353a38f Update mw.tpl 2023-02-17 15:20:52 +08:00
midoks f95684b316 Update mw.tpl 2023-02-17 15:20:39 +08:00
midoks 6fc729ccf9 Update __init__.py 2023-02-17 15:17:41 +08:00
midoks 45d0c4fc4a Update __init__.py 2023-02-17 15:16:11 +08:00
midoks 6759b9055c ip 2023-02-17 15:01:26 +08:00
midoks de694b2465 up 2023-02-17 14:56:44 +08:00
midoks c7b3daca36 up 2023-02-16 17:02:33 +08:00
midoks 452769233f up 2023-02-16 17:00:09 +08:00
midoks 8d196a3aa1 Update index.py 2023-02-16 16:26:22 +08:00
midoks 01baf509ad up 2023-02-16 15:49:55 +08:00
midoks d59ee2c843 Update install.sh 2023-02-16 15:39:08 +08:00
midoks 8919d5734e Update index.py 2023-02-16 14:15:15 +08:00
midoks bb91b30d6d Update index.py 2023-02-16 14:06:41 +08:00
midoks 103ab2e099 Update index.py 2023-02-15 22:45:44 +08:00
midoks 0d33d0db79 Update install.sh 2023-02-15 22:35:29 +08:00
midoks 6d9f4cfa08 Update tools.py 2023-02-15 22:31:22 +08:00
midoks c88c95ba21 Update macos.sh 2023-02-15 22:26:53 +08:00
midoks a705f6a8e4 Update install.sh 2023-02-15 22:24:51 +08:00
midoks 3f40ed0a01 up 2023-02-15 22:24:46 +08:00
midoks 39653896bf Update install_dev.sh 2023-02-15 22:15:08 +08:00
midoks 31d665d962 Update install.sh 2023-02-15 22:05:16 +08:00
midoks 811fa4a40d Update install_dev.sh 2023-02-15 22:04:58 +08:00
midoks 320f58424d Update README.md 2023-02-15 21:56:19 +08:00
midoks 376f0f0a4e up 2023-02-15 21:55:21 +08:00
midoks 0efb700cee Update README.md 2023-02-15 15:54:14 +08:00
midoks ff3fcae366 Update config_api.py 2023-02-15 15:50:55 +08:00
Mr Chen 22d94ce67c Merge pull request #371 from midoks/dev
安装脚本优化3
2023-02-14 22:24:04 +08:00
midoks 042fd7ac6d Update ubuntu.sh 2023-02-14 22:23:04 +08:00
midoks 1a48f52dad up 2023-02-14 22:22:06 +08:00
Mr Chen fc5970c65d Merge pull request #370 from midoks/dev
安装脚本优化2
2023-02-14 22:09:05 +08:00
midoks e758698ee2 Update debian.sh 2023-02-14 22:02:28 +08:00
Mr Chen ea03bb056a Merge pull request #369 from midoks/dev
安装脚本优化
2023-02-14 21:59:22 +08:00
midoks 088346fd5e 安装脚本优化 2023-02-14 21:58:30 +08:00
midoks cbcb686363 Update firewall_api.py 2023-02-14 21:07:22 +08:00
Mr Chen 628175a8ee Merge pull request #368 from midoks/dev
0.12.3
2023-02-14 20:13:04 +08:00
Mr Chen 96d0115257 Merge branch 'master' into dev 2023-02-14 20:12:50 +08:00
midoks 801fdf51a7 0.12.3
### 版本更新 0.12.3

* 优先使用firewalld防火墙。
* PHP[APT]加入curl扩展。
* 配置添加【未认证响应状态】功能。
* 存在ipv6时,启动时强制开启。
* OP防火墙-性能优化。
* 网站统计优化。
* 优化backup_ftp插件。
* 各种细节优化。
2023-02-14 20:11:16 +08:00
midoks 24fa3a7ca9 优化backup_ftp插件 2023-02-14 18:29:08 +08:00
midoks 3dc781498c Update index.py 2023-02-14 18:24:43 +08:00
midoks c3afaeb35a Update index.py 2023-02-14 18:23:42 +08:00
midoks 4390180a89 Update config_api.py 2023-02-14 18:20:54 +08:00
midoks 98e22f6eeb Update index.py 2023-02-14 18:19:00 +08:00
midoks 3bfd0f34f5 Update index.py 2023-02-14 18:14:27 +08:00
midoks ec8e46494a Update crontab.js 2023-02-14 18:10:14 +08:00
midoks 7cb9b0acec Update index.py 2023-02-14 17:56:16 +08:00
midoks f97d2a5987 Update ngx_debug.sh 2023-02-13 20:46:19 +08:00
midoks 5a50fe70a8 Update ngx_debug.sh 2023-02-13 20:45:57 +08:00
midoks 4ecb28575e Update install.sh 2023-02-13 20:34:25 +08:00
midoks 07bf8f162c Update debian.sh 2023-02-13 19:27:08 +08:00
midoks 19beb1bccc Update requirements.txt 2023-02-13 19:21:24 +08:00
midoks 33c27d7924 up 2023-02-13 18:56:49 +08:00
midoks a9fb6c9ec9 up 2023-02-13 18:15:10 +08:00
midoks 7198a4de95 up 2023-02-13 15:56:41 +08:00
midoks 53cb56ddf2 up 2023-02-13 15:39:57 +08:00
midoks e4582f328c Update index.py 2023-02-13 14:35:14 +08:00
midoks bb7f1b6a7d up 2023-02-13 14:16:06 +08:00
midoks 1781d879d1 up 2023-02-13 13:36:32 +08:00
midoks d89158124f Update ngx_debug.sh 2023-02-13 03:29:54 +08:00
midoks bfdad5f9a3 Update ngx_debug.sh 2023-02-13 03:23:40 +08:00
midoks 165d9ba14d Update webstats_common.lua 2023-02-13 03:05:26 +08:00
midoks ad102aa940 Update ngx_debug.sh 2023-02-13 03:01:16 +08:00
midoks 1489d15d74 Update ngx_debug.sh 2023-02-13 02:31:08 +08:00
midoks 2dbda3e6dd 优化,Linux系统不再加入到计划任务获取cpu使用率 2023-02-13 01:58:36 +08:00
midoks 4775d4f756 Update waf_common.lua 2023-02-13 01:45:49 +08:00
midoks f57fd600e6 Update test_get_cpu.lua 2023-02-13 01:38:24 +08:00
midoks bf281107b2 up 2023-02-13 00:26:31 +08:00
midoks 083fe59fa5 up 2023-02-12 17:29:29 +08:00
midoks 8f36e0ccb2 Update centos.sh 2023-02-12 02:15:12 +08:00
midoks a5b3a650eb up 2023-02-12 02:14:18 +08:00
midoks 177a08af91 Update waf_common.lua 2023-02-12 02:12:34 +08:00
midoks 5ef4b3d05d firewalld优先 2023-02-12 02:12:28 +08:00
midoks ad3d93cf8b firewalld防火墙优先 2023-02-12 02:03:57 +08:00
midoks 72643b7776 Update rhel.sh 2023-02-12 02:02:27 +08:00
midoks 45128636b0 up 2023-02-12 01:17:23 +08:00
midoks 7b962335e4 up 2023-02-12 01:08:03 +08:00
midoks c0c67095be up 2023-02-12 01:02:19 +08:00
midoks b3a0f11a80 up 2023-02-12 00:44:35 +08:00
midoks 088337765c Update webstats_worker.lua 2023-02-12 00:35:52 +08:00
midoks 066e7087c9 Update webstats_common.lua 2023-02-12 00:35:39 +08:00
midoks 29144595a6 网站统计 2023-02-12 00:22:39 +08:00
midoks 45c2b3cdca Update index.py 2023-02-11 23:44:19 +08:00
midoks e3ecdfb2b3 Update index.py 2023-02-11 23:43:51 +08:00
midoks 560d482f31 up 2023-02-11 23:25:29 +08:00
midoks 62ffc94b69 up 2023-02-11 22:34:18 +08:00
midoks 0cb10cc926 Update webstats_common.lua 2023-02-11 22:23:34 +08:00
midoks fb4eb8747c Update webstats_common.lua 2023-02-11 22:16:08 +08:00
midoks 1a26b83a46 Update webstats_log.lua 2023-02-11 22:06:04 +08:00
midoks 7c2316f005 Update webstats_common.lua 2023-02-11 21:50:32 +08:00
midoks 149baeb1fc Update webstats_log.lua 2023-02-11 21:42:57 +08:00
midoks 9714bcb419 Update init.lua 2023-02-11 17:45:17 +08:00
midoks 4e6a54dbad Update index.py 2023-02-11 17:18:24 +08:00
midoks 18498813c6 up 2023-02-11 17:06:24 +08:00
midoks 854e34a90c Update mw.py 2023-02-11 16:48:57 +08:00
midoks a0898c849e Update lua.conf 2023-02-11 16:47:46 +08:00
midoks 3a26b71828 ip 2023-02-11 16:45:28 +08:00
midoks f500dcac8b Update init_worker.lua 2023-02-11 16:06:25 +08:00
midoks 3a6e2e6e4b Update cpu_usage_file.sh 2023-02-11 16:06:08 +08:00
midoks 1d439e788c Update soft.html 2023-02-11 15:25:44 +08:00
midoks 75a2fcdaaf Update debian.sh 2023-02-11 15:24:17 +08:00
midoks 2ca8598671 up 2023-02-11 06:04:55 +08:00
midoks 2d42486ac5 Update index.py 2023-02-11 05:30:38 +08:00
midoks 24f22b5b8c up 2023-02-11 05:28:54 +08:00
midoks 68f8638638 up 2023-02-11 05:28:27 +08:00
midoks fe6b16eda4 Update index.py 2023-02-11 05:27:34 +08:00
midoks 4e35c34854 up 2023-02-11 05:24:53 +08:00
midoks cc51d9501f Update init.lua 2023-02-11 05:04:37 +08:00
midoks c08cfd4763 Update ip_white.json 2023-02-11 05:00:58 +08:00
midoks 5fdcb8bf71 up 2023-02-11 04:43:30 +08:00
midoks ce3b232c4b Update mw.py 2023-02-11 04:03:41 +08:00
midoks ec7ae65f7d up 2023-02-11 02:52:02 +08:00
midoks e4c5212ac4 Update public.js 2023-02-11 02:51:42 +08:00
midoks 23442accaf Update mw.py 2023-02-11 02:51:25 +08:00
midoks 2e6f5f9add up 2023-02-11 02:51:17 +08:00
midoks 110e356fae up 2023-02-09 17:05:06 +08:00
midoks a243d088ee Update tool_task.py 2023-02-05 16:22:17 +08:00
midoks 365fd466c2 更快获取cpu使用率 2023-02-05 16:21:30 +08:00
midoks d1304de69e Update cli.sh 2023-02-05 15:22:53 +08:00
midoks e51fa2608d Update cli.sh 2023-02-05 15:21:45 +08:00
midoks cbfcd00317 Update mw.tpl 2023-02-05 15:20:08 +08:00
midoks 7a96d3abc5 Update mw.tpl 2023-02-05 15:19:50 +08:00
midoks 33a510a5b5 Update mw.tpl 2023-02-05 12:50:26 +08:00
midoks e8942128b8 Update tool_task.py 2023-02-05 12:49:21 +08:00
midoks 7e2bd928e2 Update tool_task.py 2023-02-05 12:42:30 +08:00
midoks 89185476aa 优化获取cpu方式。 2023-02-05 12:37:49 +08:00
midoks f491641ab8 Create cpu_usage.sh 2023-02-05 12:25:57 +08:00
midoks 8b108d1aff Update ubuntu.sh 2023-02-05 12:16:55 +08:00
midoks 2cfa7ec2ab Update ubuntu.sh 2023-02-05 12:07:29 +08:00
midoks d63aae100d Update ubuntu.sh 2023-02-05 11:57:44 +08:00
midoks e8249adc53 Update tool_task.py 2023-02-05 03:48:22 +08:00
midoks 281427e479 Update tool_task.py 2023-02-05 03:48:03 +08:00
midoks af775fc77d OP防火墙-获取cpu优化 2023-02-05 03:40:18 +08:00
midoks f328354125 #362 2023-02-05 00:25:59 +08:00
midoks 1f70f962cf Update crontab.js 2023-02-05 00:25:25 +08:00
midoks 414787447e Update README.md 2023-02-04 19:27:55 +08:00
midoks 979f2174e5 Update README.md 2023-02-03 21:28:29 +08:00
midoks 84d1c96094 Update config_api.py 2023-02-03 21:17:25 +08:00
midoks 0d8d9022a0 Update mw.py 2023-02-03 21:17:07 +08:00
midoks 44d0e9e11c 存在ipv6,启动时强制开启 2023-02-03 13:42:35 +08:00
midoks 771d6e04ba Update mw.tpl 2023-02-03 13:39:45 +08:00
midoks 87563daa1d Update index.html 2023-02-02 20:50:42 +08:00
midoks 9fefb285e1 Update .gitignore 2023-02-02 20:47:18 +08:00
midoks b9ca4fc11e 配置添加【未认证响应状态】功能 2023-02-02 18:04:44 +08:00
midoks 2646d0565d Update debian.sh 2023-02-02 15:23:35 +08:00
midoks e1f900f1c5 Update tools.py 2023-02-02 14:59:15 +08:00
midoks 908b3341b2 Update rhel.sh 2023-02-01 13:25:01 +08:00
midoks 5aef2467b1 Update debian.sh 2023-02-01 13:20:53 +08:00
midoks f59114a688 自动获取ssh端口 2023-02-01 13:09:28 +08:00
midoks 363ed8b3ff Update index.py 2023-01-31 20:07:39 +08:00
midoks 3970feacc3 Update gitea.js 2023-01-31 19:48:30 +08:00
midoks f6c528149e Update gitea.js 2023-01-31 19:41:00 +08:00
midoks 8f6b5ddba9 Update gitea.js 2023-01-31 19:36:50 +08:00
midoks ef350b9fd2 Update gitea.js 2023-01-31 19:33:46 +08:00
midoks 004dfb5e7d apt php curl是必须的扩展 2023-01-30 14:01:57 +08:00
midoks 3c08d7c159 Update files_api.py 2023-01-30 01:17:09 +08:00
midoks e227204065 编码识别优化。 2023-01-30 00:50:10 +08:00
midoks ce653b7a6a Update README.md 2023-01-29 22:31:52 +08:00
Mr Chen a207215775 Merge pull request #355 from midoks/midoks-patch-1
Update debian.sh
2023-01-29 20:52:22 +08:00
Mr Chen 8115b0fb4d Update debian.sh 2023-01-29 20:48:51 +08:00
midoks 048bd573e8 修复API接口使用 2023-01-29 14:32:38 +08:00
midoks 918ea8d0f9 Update mw.tpl 2023-01-28 11:22:57 +08:00
midoks 97d2fd5a63 Update debian.sh 2023-01-28 10:50:31 +08:00
midoks 617a517048 Update index.html 2023-01-28 01:57:54 +08:00
midoks 2e7910a84c 一键迁移初始化 2023-01-28 01:34:48 +08:00
midoks 2ee4c4e3fd 页面更新跟随更新一遍环境 2023-01-27 21:58:10 +08:00
midoks 9ae4d32ed4 卸载时,删除首页显示 2023-01-27 21:05:16 +08:00
midoks 90a7f4ea10 Update .gitignore 2023-01-27 20:09:09 +08:00
midoks d22cb8305d Update soft.html 2023-01-27 20:08:34 +08:00
midoks a7a78f2103 Update .gitignore 2023-01-27 16:20:50 +08:00
Mr Chen db7ec00c07 Merge pull request #352 from midoks/dev
优化在命令行下修改端口命令
2023-01-27 16:09:29 +08:00
midoks dd21d25295 Update tools.py 2023-01-27 16:04:54 +08:00
midoks f7360aa081 Update tools.py 2023-01-27 16:02:21 +08:00
midoks 1d1ba7192a Update tools.py 2023-01-27 16:00:02 +08:00
midoks 0bf540c5e7 Update mw.py 2023-01-27 15:54:55 +08:00
104 changed files with 3823 additions and 872 deletions
+7 -1
View File
@@ -154,11 +154,16 @@ data/basic_auth.json
data/api.json
data/bind_domain.pl
plugins/vip_*
plugins/own_*
plugins/my_*
plugins/l2tp
plugins/openlitespeed
plugins/migration_api
plugins/system_safe
plugins/tamper_proof
plugins/tamper_proof_*
plugins/cryptocurrency_trade
plugins/op_load_balance
plugins/gdrive
plugins/mtproxy
plugins/zimg
@@ -171,3 +176,4 @@ plugins/file_search
debug.out
data/unauthorized_status.pl
+16 -14
View File
@@ -29,6 +29,13 @@
基本上可以使用,后续会继续优化!欢迎提供意见!
- 吹水组 - https://t.me/mdserver_web
- 交流论坛 - https://bbs.midoks.me
```
如果出现问题,最好私给我面板信息。不要让我猜。如果不提供,不要提出问题,自行解决。 — 座右铭
Talk is cheap, show me the code. -- linus
```
- [兼容性测试报告](/compatibility.md)
- [常用命令说明](/cmd.md)
@@ -38,6 +45,7 @@
* PHP[53-82] - PHP是世界上最好的编程语言。
* MySQL - 一种关系数据库管理系统。
* MariaDB - 是MySQL的一个重要分支。
* MySQL[APT/YUM] - 一种关系数据库管理系统。
* MongoDB - 一种非关系NOSQL数据库管理系统。
* phpMyAdmin - 著名Web端MySQL管理工具。
* Memcached - 一个高性能的分布式内存对象缓存系统。
@@ -66,7 +74,7 @@ phpMyAdmin[4.4.15]支持MySQL[5.5-5.7]
phpMyAdmin[5.2.0]支持MySQL[8.0]
PHP[53-72]支持phpMyAdmin[4.4.15]
PHP[72-81]支持phpMyAdmin[5.2.0]
PHP[72-82]支持phpMyAdmin[5.2.0]
```
# 特别赞助
@@ -84,27 +92,21 @@ PHP[72-81]支持phpMyAdmin[5.2.0]
# Docker
- 由[DDSRem](https://github.com/DDSRem)开发维护。
- https://hub.docker.com/r/ddsderek/mw-server
- https://hub.docker.com/r/ddsderek/mw
```
docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:443 -p 888:888 ddsderek/mw-server:latest
```
### 版本更新 0.12.2
### 版本更新 0.13.1
* 开放菜单权限配置。
* 升级SSH终端2.0。
* 增加已安装类型。
* 加入切换linux软件源的命令。
* iptables安装优化。
* 网站统计POST获取数据优化。
* mysql[apt/yum]迁移优化。
* 优化防火墙导入。
* 图标可设置。
* 关闭issue,建立bbs.midoks.me。问题集中处理,发挥群众的力量。
* 添加站操作回调钩子site_cb。 网站统计和OP防火墙不再手动重载配置
* 修复ubuntu20 pureftp 安装时,端口没有加入安全里
* 增加global_static hook关键字,并优化menu的文件加载hook
* 各种细节优化。
### JSDelivr安装地址
- 初始安装
@@ -131,7 +133,7 @@ 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
```
- 直接更新
+1 -1
View File
@@ -1522,7 +1522,7 @@ fullchain.pem 粘贴到证书输入框
self.__config['orders'][i]['auth_to'] = auth_to
# 是否到了允许重试的时间
if 'next_retry_time' in self._config['orders'][i]:
if 'next_retry_time' in self.__config['orders'][i]:
timeout = self.__config['orders'][i][
'next_retry_time'] - int(time.time())
if timeout > 0:
+65 -10
View File
@@ -27,7 +27,7 @@ from flask import request
class config_api:
__version = '0.12.2'
__version = '0.13.1'
__api_addr = 'data/api.json'
def __init__(self):
@@ -647,9 +647,22 @@ class config_api:
else:
return False, ''
def setStatusCodeApi(self):
status_code = request.form.get('status_code', '').strip()
if re.match("^\d+$", status_code):
status_code = int(status_code)
if status_code != 0:
if status_code < 100 or status_code > 999:
return mw.returnJson(False, '状态码范围错误!')
else:
return mw.returnJson(False, '状态码范围错误!')
mw.writeFile('data/unauthorized_status.pl', str(status_code))
mw.writeLog('面板设置', '将未授权响应状态码设置为:{}'.format(status_code))
return mw.returnJson(True, '设置成功!')
def getPanelTokenApi(self):
api_file = self.__api_addr
tmp = mw.readFile(api_file)
if not os.path.exists(api_file):
ready_data = {"open": False, "token": "", "limit_addr": []}
@@ -668,7 +681,7 @@ class config_api:
token = mw.getRandomString(32)
data['token'] = mw.md5(token)
data['token_crypt'] = mw.enCrypt(
data['token'], token).decode('utf-8')
data['token'], token)
mw.writeFile(api_file, json.dumps(data))
data['token'] = "***********************************"
@@ -680,10 +693,6 @@ class config_api:
def setPanelTokenApi(self):
op_type = request.form.get('op_type', '').strip()
api_file = self.__api_addr
tmp = mw.readFile(api_file)
data = json.loads(tmp)
if op_type == '1':
token = mw.getRandomString(32)
data['token'] = mw.md5(token)
@@ -693,7 +702,14 @@ class config_api:
mw.writeFile(api_file, json.dumps(data))
return mw.returnJson(True, 'ok', token)
elif op_type == '2':
api_file = self.__api_addr
if not os.path.exists(api_file):
return mw.returnJson(False, "先在API接口配置")
else:
tmp = mw.readFile(api_file)
data = json.loads(tmp)
if op_type == '2':
data['open'] = not data['open']
stats = {True: '开启', False: '关闭'}
if not 'token_crypt' in data:
@@ -708,12 +724,38 @@ class config_api:
return mw.returnJson(not not data['open'], token)
elif op_type == '3':
limit_addr = request.form.get('limit_addr', '').strip()
data['limit_addr'] = limit_addr.split('\n')
mw.writeLog('API配置', '变更IP限制为[%s]' % limit_addr)
mw.writeFile(api_file, json.dumps(data))
return mw.returnJson(True, '保存成功!')
def renderUnauthorizedStatus(self, data):
cfg_unauth_status = 'data/unauthorized_status.pl'
if os.path.exists(cfg_unauth_status):
status_code = mw.readFile(cfg_unauth_status)
data['status_code'] = status_code
data['status_code_msg'] = status_code
if status_code == '0':
data['status_code_msg'] = "默认-安全入口错误提示"
elif status_code == '400':
data['status_code_msg'] = "400-客户端请求错误"
elif status_code == '401':
data['status_code_msg'] = "401-未授权访问"
elif status_code == '403':
data['status_code_msg'] = "403-拒绝访问"
elif status_code == '404':
data['status_code_msg'] = "404-页面不存在"
elif status_code == '408':
data['status_code_msg'] = "408-客户端超时"
elif status_code == '416':
data['status_code_msg'] = "416-无效的请求"
else:
data['status_code'] = '0'
data['status_code_msg'] = "默认-安全入口错误提示"
return data
def get(self):
data = {}
@@ -766,6 +808,8 @@ class config_api:
else:
data['bind_domain'] = ''
data = self.renderUnauthorizedStatus(data)
api_token = self.__api_addr
if os.path.exists(api_token):
bac = mw.readFile(api_token)
@@ -780,7 +824,9 @@ class config_api:
data['username'] = mw.M('users').where(
"id=?", (1,)).getField('username')
# databases hook 获取
data['hook_tag'] = request.args.get('tag', '')
# databases hook
database_hook_file = 'data/hook_database.json'
if os.path.exists(database_hook_file):
df = mw.readFile(database_hook_file)
@@ -789,7 +835,7 @@ class config_api:
else:
data['hook_database'] = []
# menu hook 获取
# menu hook
menu_hook_file = 'data/hook_menu.json'
if os.path.exists(menu_hook_file):
df = mw.readFile(menu_hook_file)
@@ -798,4 +844,13 @@ class config_api:
else:
data['hook_menu'] = []
# global_static hook
global_static_hook_file = 'data/hook_global_static.json'
if os.path.exists(global_static_hook_file):
df = mw.readFile(global_static_hook_file)
df = json.loads(df)
data['hook_global_static'] = df
else:
data['hook_global_static'] = []
return data
+1 -1
View File
@@ -348,7 +348,7 @@ class Sql():
except Exception as ex:
return "error: " + str(ex)
def query(self, sql, param):
def query(self, sql, param=()):
# 执行SQL语句返回数据集
self.__getConn()
try:
+132 -53
View File
@@ -247,8 +247,8 @@ class files_api:
os.remove(task_log)
return mw.returnJson(True, '任务已删除!')
# 上传文件
def uploadFileApi(self):
# 上传文件
from werkzeug.utils import secure_filename
from flask import request
@@ -263,6 +263,8 @@ class files_api:
if os.path.exists(filename):
s_path = filename
p_stat = os.stat(s_path)
# print(filename)
f.save(filename)
os.chown(filename, p_stat.st_uid, p_stat.st_gid)
os.chmod(filename, p_stat.st_mode)
@@ -271,6 +273,86 @@ class files_api:
mw.writeLog('文件管理', msg)
return mw.returnMsg(True, '上传成功!')
# 设置文件和目录权限
def setMode(self, path):
s_path = os.path.dirname(path)
p_stat = os.stat(s_path)
os.chown(path, p_stat.st_uid, p_stat.st_gid)
os.chmod(path, p_stat.st_mode)
def uploadSegmentApi(self):
# 分段上传
path = request.form.get('path', '')
name = request.form.get('name', '')
size = request.form.get('size')
start = request.form.get('start')
dir_mode = request.form.get('dir_mode', '')
file_mode = request.form.get('file_mode', '')
if not mw.fileNameCheck(name):
return mw.returnJson(False, '文件名中不能包含特殊字符!')
if path == '/':
return mw.returnJson(False, '不能直接上传文件到系统根目录!')
if name.find('./') != -1 or path.find('./') != -1:
return mw.returnJson(False, '错误的参数')
if not os.path.exists(path):
os.makedirs(path, 493)
if not dir_mode != '' or not file_mode != '':
mw.setMode(path)
save_path = os.path.join(
path, name + '.' + str(int(size)) + '.upload.tmp')
d_size = 0
if os.path.exists(save_path):
d_size = os.path.getsize(save_path)
if d_size != int(start):
return str(d_size)
f = open(save_path, 'ab')
b64_data = request.form.get('b64_data', '0')
if b64_data == '1':
import base64
b64_data = base64.b64decode(args.b64_data)
f.write(b64_data)
else:
upload_files = request.files.getlist("blob")
for tmp_f in upload_files:
f.write(tmp_f.read())
f.close()
f_size = os.path.getsize(save_path)
if f_size != int(size):
return str(f_size)
new_name = os.path.join(path, name)
if os.path.exists(new_name):
if new_name.find('.user.ini') != -1:
mw.execShell("chattr -i " + new_name)
try:
os.remove(new_name)
except:
mw.execShell("rm -f %s" % new_name)
os.renames(save_path, new_name)
if dir_mode != '' and dir_mode != '':
mode_tmp1 = dir_mode.split(',')
mw.setMode(path, mode_tmp1[0])
mw.setOwn(path, mode_tmp1[1])
mode_tmp2 = file_mode.split(',')
mw.setMode(new_name, mode_tmp2[0])
mw.setOwn(new_name, mode_tmp2[1])
else:
self.setMode(new_name)
msg = mw.getInfo('上传文件[{1}] 到 [{2}]成功!', (new_name, path))
mw.writeLog('文件管理', msg)
return mw.returnMsg(True, '上传成功!')
def getRecycleBinApi(self):
rPath = self.rPath
if not os.path.exists(rPath):
@@ -626,7 +708,7 @@ class files_api:
return not path in nDirs
def getDirSize(self, path):
if mw.getOs() == 'darwin':
if mw.isAppleSystem():
tmp = mw.execShell('du -sh ' + path)
else:
tmp = mw.execShell('du -sbh ' + path)
@@ -677,56 +759,29 @@ class files_api:
if os.path.getsize(path) > 2097152:
return mw.returnJson(False, '不能在线编辑大于2MB的文件!')
if os.path.isdir(path):
return mw.returnJson(False, '这不是一个文件!')
fp = open(path, 'rb')
data = {}
data['status'] = True
try:
if fp:
from chardet.universaldetector import UniversalDetector
detector = UniversalDetector()
srcBody = b""
for line in fp.readlines():
detector.feed(line)
srcBody += line
detector.close()
char = detector.result
data['encoding'] = char['encoding']
if char['encoding'] == 'GB2312' or not char['encoding'] or char[
'encoding'] == 'TIS-620' or char['encoding'] == 'ISO-8859-9':
data['encoding'] = 'GBK'
if char['encoding'] == 'ascii' or char[
'encoding'] == 'ISO-8859-1':
data['encoding'] = 'utf-8'
if char['encoding'] == 'Big5':
data['encoding'] = 'BIG5'
if not data['encoding'] in ['GBK', 'utf-8', 'BIG5']:
data['encoding'] = 'utf-8'
if fp:
srcBody = fp.read()
fp.close()
encoding_list = ['utf-8', 'GBK', 'BIG5']
for el in encoding_list:
try:
if sys.version_info[0] == 2:
data['data'] = srcBody.decode(
data['encoding']).encode('utf-8', errors='ignore')
else:
data['data'] = srcBody.decode(data['encoding'])
except:
data['encoding'] = char['encoding']
if sys.version_info[0] == 2:
data['data'] = srcBody.decode(
data['encoding']).encode('utf-8', errors='ignore')
else:
data['data'] = srcBody.decode(data['encoding'])
return mw.returnJson(True, 'OK', data)
else:
if sys.version_info[0] == 2:
data['data'] = srcBody.decode('utf-8').encode('utf-8')
else:
data['data'] = srcBody.decode('utf-8')
data['encoding'] = 'utf-8'
data['encoding'] = el
data['data'] = srcBody.decode(data['encoding'])
break
except Exception as ex:
if el == 'BIG5':
return mw.returnJson(False, '文件编码不被兼容,无法正确读取文件!' + str(ex))
else:
return mw.returnJson(False, '文件未正常打开!')
return mw.returnJson(True, 'OK', data)
except Exception as ex:
return mw.returnJson(False, '文件编码不被兼容,无法正确读取文件!' + str(ex))
return mw.returnJson(True, 'OK', data)
def saveBody(self, path, data, encoding='utf-8'):
if not os.path.exists(path):
@@ -734,13 +789,10 @@ class files_api:
try:
if encoding == 'ascii':
encoding = 'utf-8'
if sys.version_info[0] == 2:
data = data.encode(encoding, errors='ignore')
fp = open(path, 'w+')
else:
data = data.encode(
encoding, errors='ignore').decode(encoding)
fp = open(path, 'w+', encoding=encoding)
data = data.encode(
encoding, errors='ignore').decode(encoding)
fp = open(path, 'w+', encoding=encoding)
fp.write(data)
fp.close()
@@ -935,6 +987,33 @@ class files_api:
return mw.getJson(data)
def execShellApi(self):
# 执行SHELL命令
shell = request.form.get('shell', '').strip()
path = request.form.get('path', '').strip()
disabled = ['vi', 'vim', 'top', 'passwd', 'su']
tmp = shell.split(' ')
if tmp[0] in disabled:
return mw.returnJson(False, '禁止执行[{}]'.format(tmp[0]))
shellStr = '''#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
cd %s
%s
''' % (path, shell)
mw.writeFile('/tmp/panelShell.sh', shellStr)
mw.execShell(
'nohup bash /tmp/panelShell.sh > /tmp/panelShell.pl 2>&1 &')
return mw.returnJson(True, 'ok')
def getExecShellMsgApi(self):
# 取SHELL执行结果
fileName = '/tmp/panelShell.pl'
if not os.path.exists(fileName):
return ''
status = not mw.processExists('bash', None, '/tmp/panelShell.sh')
return mw.returnJson(status, mw.getNumLines(fileName, 200))
def __get_stats(self, filename, path=None):
filename = filename.replace('//', '/')
try:
+14 -13
View File
@@ -34,13 +34,13 @@ class firewall_api:
def __init__(self):
iptables_file = mw.systemdCfgDir() + '/iptables.service'
if os.path.exists(iptables_file):
self.__isIptables = True
if os.path.exists('/usr/sbin/firewalld'):
self.__isFirewalld = True
if os.path.exists('/usr/sbin/ufw'):
elif os.path.exists('/usr/sbin/ufw'):
self.__isUfw = True
if mw.isAppleSystem():
elif os.path.exists(iptables_file):
self.__isIptables = True
elif mw.isAppleSystem():
self.__isMac = True
##### ----- start ----- ###
@@ -123,12 +123,12 @@ class firewall_api:
address = port
if self.__isUfw:
mw.execShell('ufw delete deny from ' + address + ' to any')
elif self.__isIptables:
cmd = 'iptables -D INPUT -s ' + address + ' -j DROP'
mw.execShell(cmd)
elif self.__isFirewalld:
mw.execShell(
'firewall-cmd --permanent --remove-rich-rule=\'rule family=ipv4 source address="' + address + '" drop\'')
elif self.__isIptables:
cmd = 'iptables -D INPUT -s ' + address + ' -j DROP'
mw.execShell(cmd)
else:
pass
@@ -149,14 +149,15 @@ class firewall_api:
return mw.returnJson(False, '失败,不能删除当前面板端口!')
if self.__isUfw:
mw.execShell('ufw delete allow ' + port + '/tcp')
elif self.__isIptables:
mw.execShell(
'iptables -D INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT')
elif self.__isFirewalld:
port = port.replace(':', '-')
mw.execShell(
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/tcp')
mw.execShell(
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/udp')
elif self.__isIptables:
mw.execShell(
'iptables -D INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT')
else:
pass
msg = mw.getInfo('删除防火墙放行端口[{1}]成功!', (port,))
@@ -438,13 +439,13 @@ class firewall_api:
def addAcceptPort(self, port):
if self.__isUfw:
mw.execShell('ufw allow ' + port + '/tcp')
elif self.__isIptables:
cmd = 'iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT'
mw.execShell(cmd)
elif self.__isFirewalld:
port = port.replace(':', '-')
cmd = 'firewall-cmd --permanent --zone=public --add-port=' + port + '/tcp'
mw.execShell(cmd)
elif self.__isIptables:
cmd = 'iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT'
mw.execShell(cmd)
else:
pass
return True
+162 -8
View File
@@ -123,6 +123,23 @@ def getAcmeDir():
return acme
def getAcmeDomainDir(domain):
acme_dir = getAcmeDir()
acme_domain = acme_dir + '/' + domain
acme_domain_ecc = acme_domain + '_ecc'
if os.path.exists(acme_domain_ecc):
acme_domain = acme_domain_ecc
return acme_domain
def fileNameCheck(filename):
f_strs = [';', '&', '<', '>']
for fs in f_strs:
if filename.find(fs) != -1:
return False
return True
def triggerTask():
isTask = getRunDir() + '/tmp/panelTask.pl'
writeFile(isTask, 'True')
@@ -228,6 +245,14 @@ def isIpAddr(ip):
return False
def getWebStatus():
pid = getServerDir() + '/openresty/nginx/logs/nginx.pid'
if os.path.exists(pid):
return True
return False
# ------------------------------ openresty start -----------------------------
def restartWeb():
return opWeb("reload")
@@ -252,6 +277,63 @@ def opWeb(method):
return False
def opLuaMake(cmd_name):
path = getServerDir() + '/web_conf/nginx/lua/lua.conf'
root_dir = getServerDir() + '/web_conf/nginx/lua/' + cmd_name
dst_path = getServerDir() + '/web_conf/nginx/lua/' + cmd_name + '.lua'
def_path = getServerDir() + '/web_conf/nginx/lua/empty.lua'
if not os.path.exists(root_dir):
execShell('mkdir -p ' + root_dir)
files = []
for fl in os.listdir(root_dir):
suffix = getFileSuffix(fl)
if suffix != 'lua':
continue
flpath = os.path.join(root_dir, fl)
files.append(flpath)
if len(files) > 0:
def_path = dst_path
content = ''
for f in files:
t = readFile(f)
f_base = os.path.basename(f)
content += '-- ' + '*' * 20 + ' ' + f_base + ' start ' + '*' * 20 + "\n"
content += t
content += "\n" + '-- ' + '*' * 20 + ' ' + f_base + ' end ' + '*' * 20 + "\n"
writeFile(dst_path, content)
else:
if os.path.exists(dst_path):
os.remove(dst_path)
conf = readFile(path)
conf = re.sub(cmd_name + ' (.*);',
cmd_name + " " + def_path + ";", conf)
writeFile(path, conf)
def opLuaInitFile():
opLuaMake('init_by_lua_file')
def opLuaInitWorkerFile():
opLuaMake('init_worker_by_lua_file')
def opLuaInitAccessFile():
opLuaMake('access_by_lua_file')
def opLuaMakeAll():
opLuaInitFile()
opLuaInitWorkerFile()
opLuaInitAccessFile()
# ------------------------------ openresty end -----------------------------
def restartMw():
import system_api
system_api.system_api().restartMw()
@@ -462,15 +544,15 @@ def getDataFromInt(val):
def writeLog(stype, msg, args=()):
# 写日志
uid = 1
try:
from flask import session
uid = 1
if 'uid' in session:
uid = session['uid']
return writeDbLog(stype, msg, args, uid)
except Exception as e:
print(getTracebackInfo())
return False
pass
# print(getTracebackInfo())
return writeDbLog(stype, msg, args, uid)
def writeDbLog(stype, msg, args=(), uid=1):
@@ -580,7 +662,7 @@ def enCrypt(key, strings):
# 加密字符串
try:
import base64
_key = md5(key).encode('utf-8')
_key = key.encode('utf-8')
_key = base64.urlsafe_b64encode(_key)
if type(strings) != bytes:
@@ -596,6 +678,44 @@ def enCrypt(key, strings):
def deCrypt(key, strings):
# 解密字符串
try:
import base64
_key = key.encode('utf-8')
_key = base64.urlsafe_b64encode(_key)
if type(strings) != bytes:
strings = strings.encode('utf-8')
from cryptography.fernet import Fernet
f = Fernet(_key)
result = f.decrypt(strings).decode('utf-8')
return result
except:
print(getTracebackInfo())
return strings
def enDoubleCrypt(key, strings):
# 加密字符串
try:
import base64
_key = md5(key).encode('utf-8')
_key = base64.urlsafe_b64encode(_key)
if type(strings) != bytes:
strings = strings.encode('utf-8')
import cryptography
from cryptography.fernet import Fernet
f = Fernet(_key)
result = f.encrypt(strings)
return result.decode('utf-8')
except:
print(getTracebackInfo())
return strings
def deDoubleCrypt(key, strings):
# 解密字符串
try:
import base64
@@ -885,7 +1005,7 @@ def getLocalIp():
try:
ipaddress = readFile(filename)
if not ipaddress or ipaddress == '127.0.0.1':
cmd = "curl -4 -sS --connect-timeout 5 -m 60 https://v6r.ipip.net/?format=text"
cmd = "curl --insecure -4 -sS --connect-timeout 5 -m 60 https://v6r.ipip.net/?format=text"
ip = execShell(cmd)
result = ip[0].strip()
if result == '':
@@ -894,7 +1014,7 @@ def getLocalIp():
return result
return ipaddress
except Exception as e:
cmd = "curl -6 -sS --connect-timeout 5 -m 60 https://v6r.ipip.net/?format=text"
cmd = "curl --insecure -6 -sS --connect-timeout 5 -m 60 https://v6r.ipip.net/?format=text"
ip = execShell(cmd)
result = ip[0].strip()
if result == '':
@@ -1019,6 +1139,15 @@ def setOwn(filename, user, group=None):
return True
def setMode(filename, mode):
# 设置文件权限
if not os.path.exists(filename):
return False
mode = int(str(mode), 8)
os.chmod(filename, mode)
return True
def checkPort(port):
# 检查端口是否合法
ports = ['21', '443', '888']
@@ -1104,7 +1233,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'
@@ -1511,6 +1640,31 @@ def getSshDir():
return '/root/.ssh'
def processExists(pname, exe=None, cmdline=None):
# 进程是否存在
try:
import psutil
pids = psutil.pids()
for pid in pids:
try:
p = psutil.Process(pid)
if p.name() == pname:
if not exe and not cmdline:
return True
else:
if exe:
if p.exe() == exe:
return True
if cmdline:
if cmdline in p.cmdline():
return True
except:
pass
return False
except:
return True
def createRsa():
# ssh-keygen -t rsa -P "" -C "midoks@163.com"
ssh_dir = getSshDir()
+7 -5
View File
@@ -91,7 +91,7 @@ class plugins_api:
t = mw.readFile(menu_file)
tlist = json.loads(t)
for menu_data in tlist:
if 'path' in menu_data:
if tag == menu_data['name'] and 'path' in menu_data:
tpath = self.menuGetAbsPath(tag, menu_data['path'])
content = mw.readFile(tpath)
data['plugin_content'] = content
@@ -256,13 +256,14 @@ class plugins_api:
data = json.loads(t)
for idx in range(len(data)):
if data[idx]['title'] == info['title'] and data[idx]['name'] == info['name']:
if data[idx]['name'] == info['name']:
data.remove(data[idx])
break
mw.writeFile(hookPath, json.dumps(data))
def hookInstall(self, info):
valid_hook = ['backup', 'database']
valid_list_hook = ['menu']
valid_list_hook = ['menu', 'global_static', 'site_cb']
if 'hook' in info:
hooks = info['hook']
for h in hooks:
@@ -280,7 +281,7 @@ class plugins_api:
def hookUninstall(self, info):
valid_hook = ['backup', 'database']
valid_list_hook = ['menu']
valid_list_hook = ['menu', 'global_static', 'site_cb']
if 'hook' in info:
hooks = info['hook']
for h in hooks:
@@ -795,7 +796,8 @@ class plugins_api:
for index in range(len(tmp_data)):
plugins_info.append(tmp_data[index])
except Exception as e:
print(e)
print(json_file)
print(mw.getTracebackInfo())
start = (page - 1) * pageSize
end = start + pageSize
+42 -10
View File
@@ -72,6 +72,30 @@ class site_api:
mw.execShell("mkdir -p " + self.sslLetsDir +
" && chmod -R 755 " + self.sslLetsDir)
def runHook(self, hook_name, func_name):
# 站点操作Hook
hook_file = 'data/hook_site_cb.json'
hook_cfg = []
if os.path.exists(hook_file):
t = mw.readFile(hook_file)
hook_cfg = json.loads(t)
hook_num = len(hook_cfg)
if hook_num == 0:
return
import plugins_api
pa = plugins_api.plugins_api()
for x in range(hook_num):
hook_data = hook_cfg[x]
if func_name in hook_data:
app_name = hook_data["name"]
run_func = hook_data[func_name]['func']
# print(app_name, run_func)
pa.run(app_name, run_func)
return True
##### ----- start ----- ###
def listApi(self):
limit = request.form.get('limit', '10')
@@ -550,7 +574,7 @@ class site_api:
return mw.returnJson(False, '使用中,先关闭再删除')
mw.execShell('rm -rf ' + ssl_lets_dir)
elif ssl_type == 'acme':
ssl_acme_dir = mw.getAcmeDir() + '/' + site_name
ssl_acme_dir = mw.getAcmeDomainDir(site_name)
csr_acme_path = ssl_acme_dir + '/fullchain.cer' # 生成证书路径
if mw.md5(mw.readFile(csr_acme_path)) == mw.md5(mw.readFile(csr_path)):
return mw.returnJson(False, '使用中,先关闭再删除')
@@ -587,9 +611,9 @@ class site_api:
csr_path = self.sslLetsDir + '/' + site_name + '/fullchain.pem' # 生成证书路径
key_path = self.sslLetsDir + '/' + site_name + '/privkey.pem' # 密钥文件路径
elif ssl_type == 'acme':
csr_path = mw.getAcmeDir() + '/' + site_name + '/fullchain.cer' # 生成证书路径
key_path = mw.getAcmeDir() + '/' + site_name + '/' + \
site_name + '.key' # 密钥文件路径
acme_dir = mw.getAcmeDomainDir(site_name)
csr_path = acme_dir + '/fullchain.cer' # 生成证书路径
key_path = acme_dir + '/' + site_name + '.key' # 密钥文件路径
key = mw.readFile(key_path)
csr = mw.readFile(csr_path)
@@ -989,16 +1013,17 @@ class site_api:
# print(cmd)
result = mw.execShell(cmd)
src_path = acme_dir + '/' + domains[0]
src_path = mw.getAcmeDomainDir(domains[0])
src_cert = src_path + '/fullchain.cer'
src_key = src_path + '/' + domains[0] + '.key'
src_cert.replace("\*", "*")
msg = '签发失败,您尝试申请证书的失败次数已达上限!<p>1、检查域名是否绑定到对应站点</p>\
<p>2、检查域名是否正确解析到本服务器,或解析还未完全生效</p>\
<p>3、如果您的站点设置了反向代理,或使用了CDN,请先将其关闭</p>\
<p>4、如果您的站点设置了301重定向,请先将其关闭</p>\
<p>5、如果以上检查都确认没有问题,请尝试更换DNS服务商</p>'
if not os.path.exists(src_cert.replace("\*", "*")):
if not os.path.exists(src_cert):
data = {}
data['err'] = result
data['out'] = result[0]
@@ -1271,6 +1296,7 @@ class site_api:
mw.M('domain').add('pid,name,port,addtime',
(pid, domain_name, domain_port, mw.getDate()))
self.runHook('site_cb', 'add')
return mw.returnJson(True, '域名添加成功!')
def addDirBindApi(self):
@@ -1400,7 +1426,7 @@ class site_api:
data['filename'] = filename
return mw.getJson(data)
# 修改物理路径
# 修改物理路径
def setPathApi(self):
mid = request.form.get('id', '')
path = request.form.get('path', '')
@@ -2529,16 +2555,18 @@ location ^~ {from} {\n\
self.createRootDir(self.sitePath)
self.nginxAddConf()
mw.M('domain').add('pid,name,port,addtime',
(pid, self.siteName, self.sitePort, mw.getDate()))
# 添加更多域名
for domain in siteMenu['domainlist']:
self.addDomain(domain, self.siteName, pid)
mw.M('domain').add('pid,name,port,addtime',
(pid, self.siteName, self.sitePort, mw.getDate()))
data = {}
data['siteStatus'] = False
mw.restartWeb()
self.runHook('site_cb', 'add')
return mw.returnJson(True, '添加成功')
def deleteWSLogs(self, webname):
@@ -2588,6 +2616,8 @@ location ^~ {from} {\n\
mw.execShell('rm -rf ' + ssl_acme_dir)
mw.M('sites').where("id=?", (sid,)).delete()
mw.M('domain').where("pid=?", (sid,)).delete()
mw.M('domain').where("name=?", (webname,)).delete()
# binding domain delete
binding_list = mw.M('binding').field(
@@ -2605,6 +2635,8 @@ location ^~ {from} {\n\
mw.M('binding').where("pid=?", (sid,)).delete()
mw.restartWeb()
self.runHook('site_cb', 'delete')
return mw.returnJson(True, '站点删除成功!')
def setEndDate(self, sid, edate):
+1 -1
View File
@@ -320,7 +320,7 @@ class ssh_terminal:
def getSshInfo(self, file):
rdata = mw.readFile(file)
destr = mw.deCrypt('mdserver-web', rdata)
destr = mw.enDoubleCrypt('mdserver-web', rdata)
return json.loads(destr)
def setAttr(self, sid, info):
+47
View File
@@ -166,6 +166,33 @@ class system_api:
except:
return False
def getEnvInfoApi(self, get=None):
serverInfo = {}
serverInfo['status'] = True
sdir = mw.getServerDir()
serverInfo['webserver'] = '未安装'
if os.path.exists(sdir + '/openresty/nginx/sbin/nginx'):
serverInfo['webserver'] = 'OpenResty'
serverInfo['php'] = []
phpversions = ['52', '53', '54', '55', '56', '70', '71',
'72', '73', '74', '80', '81', '82', '83', '84']
phpPath = sdir + '/php/'
for pv in phpversions:
if not os.path.exists(phpPath + pv + '/bin/php'):
continue
serverInfo['php'].append(pv)
serverInfo['mysql'] = False
if os.path.exists(sdir + '/mysql/bin/mysql'):
serverInfo['mysql'] = True
import psutil
try:
diskInfo = psutil.disk_usage('/www')
except:
diskInfo = psutil.disk_usage('/')
serverInfo['disk'] = diskInfo[2]
return mw.returnJson(True, 'ok', serverInfo)
def getPanelInfo(self, get=None):
# 取面板配置
address = mw.GetLocalIp()
@@ -724,6 +751,26 @@ class system_api:
mw.execShell('rm -rf ' + toPath + '/mdserver-web-' + version)
mw.execShell('rm -rf ' + toPath + '/mw.zip')
update_env = '''
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
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
else
cd /www/server/mdserver-web && source /www/server/mdserver-web/bin/activate
fi
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
PIPSRC="https://pypi.python.org/simple"
if [ ! -z "$cn" ];then
PIPSRC="https://pypi.tuna.tsinghua.edu.cn/simple"
fi
cd /www/server/mdserver-web && pip3 install -r /www/server/mdserver-web/requirements.txt -i $PIPSRC
'''
os.system(update_env)
self.restartMw()
return mw.returnJson(True, '安装更新成功!')
+8 -8
View File
@@ -21,12 +21,12 @@ mw_start_task()
sleep 0.3
isStart=$(ps aux |grep 'task.py'|grep -v grep|awk '{print $2}')
if [ "$isStart" == '' ];then
echo -e "\033[31mfailed\033[0m"
echo '------------------------------------------------------'
tail -n 20 $DIR/logs/task.log
echo '------------------------------------------------------'
echo -e "\033[31mError: mw-tasks service startup failed.\033[0m"
return;
echo -e "\033[31mfailed\033[0m"
echo '------------------------------------------------------'
tail -n 20 $DIR/logs/task.log
echo '------------------------------------------------------'
echo -e "\033[31mError: mw-tasks service startup failed.\033[0m"
return;
fi
echo -e "\033[32mdone\033[0m"
else
@@ -62,14 +62,14 @@ mw_stop()
PLIST=`ps -ef|grep app:app |grep -v grep|awk '{print $2}'`
for i in $PLIST
do
kill -9 $i
kill -9 $i > /dev/null 2>&1
done
pids=`ps -ef|grep task.py | grep -v grep |awk '{print $2}'`
arr=($pids)
for p in ${arr[@]}
do
kill -9 $p
kill -9 $p > /dev/null 2>&1
done
}
+8 -5
View File
@@ -194,14 +194,17 @@ def backupAllFunc(stype):
'/scripts/backup.py ' + args
os.system(cmd)
# 开始执行上传信息
bk_prefix = prefix_dict[stype]
bk_name = stype
# 开始执行上传信息.
if stype.find('database_') > -1:
bk_name = 'database'
plugin_name = stype.replace('database_', '')
bk_prefix = plugin_name + '/db'
stype = 'database'
else:
bk_prefix = prefix_dict[stype]
bk_name = stype
find_path = mw.getBackupDir() + '/' + bk_name + '/' + bk_prefix + '_' + name
find_new_file = "ls " + find_path + \
@@ -212,10 +215,10 @@ def backupAllFunc(stype):
mw.echoInfo("not find upload file!")
return False
print("|-准备上传文件 {}".format(filename))
ftp = FtpPSClient()
ftp.uploadFile(filename, stype)
return True
return ''
def backupSite():
+5 -1
View File
@@ -33,7 +33,11 @@ if [ ! -d $WEB_PATH ];then
mkdir -p $WEB_PATH
rsync -vauP --delete --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
else
rsync -vauP --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
if [ -f $GIT_PROJECT_DIR/exclude.list ];then
rsync -vauP --delete --exclude-from="$GIT_PROJECT_DIR/exclude.list" $GIT_PROJECT_DIR/ $WEB_PATH
else
rsync -vauP --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
fi
fi
sysName=`uname`
+2 -2
View File
@@ -8,8 +8,8 @@
<p onclick="pluginConfig('gitea',null, 'conf');">配置文件</p>
<p onclick="gogsSetConfig();">配置修改</p>
<p onclick="giteaUserList();">用户列表</p>
<p onclick="pluginLogs('gitea',null,'run_log');">运行日志</p>
<p onclick="pluginLogs('gitea',null,'post_receive_log');" title="提交post-receive日志">提交日志</p>
<!-- <p onclick="pluginLogs('gitea',null,'run_log');">运行日志</p> -->
<!-- <p onclick="pluginLogs('gitea',null,'post_receive_log');" title="提交post-receive日志">提交日志</p> -->
<p onclick="giteaRead();">使用说明</p>
</div>
<div class="bt-w-con pd15">
+1 -1
View File
@@ -560,7 +560,7 @@ def userProjectList():
data['data'] = ret_data
data['args'] = args
data['list'] = mw.getPage(
{'count': dlist_sum, 'p': page, 'row': page_size, 'tojs': 'userProjectList'})
{'count': dlist_sum, 'p': page, 'row': page_size, 'tojs': 'userProjectListPost'})
return mw.returnJson(True, 'OK', data)
+3 -2
View File
@@ -187,7 +187,7 @@ function userProjectList(user, search){
<thead><tr><th>项目</th><th>操作</th></tr></thead>\
<tbody></tbody>\
</table>\
<div class='dataTables_paginate paging_bootstrap pagination' style='margin-top:0px;'><ul id='gitea_page' class='page'></ul></div>\
<div class='dataTables_paginate paging_bootstrap pagination' style='margin-top:0px;'><ul class='page'><div class='gitea_page'></div></ul></div>\
</div>\
</div>\
</div>",
@@ -230,7 +230,8 @@ function userProjectListPost(user, search){
var project_list = rdata['data']['data'];
for (i in project_list) {
var name = project_list[i]['name'];
list += '<tr><td>'+name+'</td>\
list += '<tr>\
<td>'+name+'</td>\
<td>\
<a class="btlink" target="_blank" href="'+rdata['data']['root_url']+user+'/'+name+'">源码</a> | \
<a class="btlink" onclick="projectScript(\''+user+'\',\''+name+'\','+project_list[i]['has_hook']+');">脚本</a>\
+5 -2
View File
@@ -62,13 +62,16 @@ def getArgs():
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':')
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
Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

+292
View File
@@ -0,0 +1,292 @@
<style>
.migration_content {
position: relative;
height: 450px;
}
.step_head::after {
background-color: #ddd;
border-top: 2px solid #ccc;
content: "";
display: block;
height: 3px;
left: 84px;
position: absolute;
top: 14px;
width: 500px;
z-index: -1;
}
.step_head {
margin: 20px 0;
}
.step_head ul li {
width: 24.5%;
display: inline-block;
}
.step_head ul li span {
width: 30px;
height: 30px;
line-height: 30px;
display: block;
border-radius: 15px;
background-color: #ddd;
color: #878787;
margin: 0 auto;
text-align: center;
font-size: 16px;
font-weight: 600;
}
.step_head ul li p {
text-align: center;
margin-top: 15px;
}
.step_head ul li.active span {
background-color: #20A53A;
color: #fff;
}
.step_content {
text-align: center;
}
.boxHide {
display: none
}
.step_content .psync_info input {
width: 300px;
}
.step_content .psync_info .panel_setp_span {
height: 32px;
line-height: 32px;
overflow: hidden;
padding-right: 20px;
text-align: right;
text-overflow: ellipsis;
white-space: nowrap;
width: 130px;
display: inline-block;
float: left;
}
.step_content .psync_info .mtb20{
padding-left: 40px;
text-align: left;
}
.psync_path .table {
text-align: left;
}
.psync_path .table > tbody > tr > td:nth-child(2n),
.psync_path .table > thead > tr > th:nth-child(2n),
.terlist .table > thead > tr > th:nth-child(2n),
.terlist .table > tbody > tr > td:nth-child(2n),
.terlist .table > tbody > tr > td:nth-child(1),
.terlist .table > thead > tr > th:nth-child(1) {
border-right: #ddd 1px solid;
}
.checkbox_conten {
background-color: #f3f3f3;
border: #ddd 1px solid;
border-radius: 4px;
padding: 10px;
margin: 0px 50px;
}
.checkbox_item span {
display: inline-block;
height: 15px;
overflow: hidden;
text-align: left;
display: block;
padding-left: 20px;
height: 20px;
line-height: 20px;
width: 152px;
text-overflow: ellipsis;
}
label.checkbox_label {
margin-left: 6px;
margin-bottom: 0;
}
label.checkbox_label span {
color: #000;
}
.psync_data {
display: none;
}
.psync_data .checkbox_item input[type="checkbox"] {
width: 15px;
height: 15px;
position: absolute;
top: 50%;
margin-top: -6px;
}
.checkbox_item label {
font-weight: normal;
white-space: nowrap;
position: relative;
}
.psync_data .checkbox_data {
margin: 0 5px 5px;
display: inline-block;
width: 166px;
vertical-align: text-top;
}
.psync_data .checkbox_data:last-child {
margin-right: 0;
}
.checkbox_item ul {
background-color: #fff;
max-height: 174px;
overflow: auto;
width: 100%;
display: block;
margin-top: 10px;
}
.checkbox_item ul li {
padding: 0 6px;
}
.psync_data .checkbox_con {
display: block
}
.progress {
background-color: #e2e2e2;
border-radius: 8px;
height: 16px;
line-height: 16px;
position: relative;
}
.progress-bar {
background-color: #5ab76c;
border-radius: 8px;
height: 16px;
max-width: 100%;
position: absolute;
text-align: right;
transition: all 0.3s ease 0s;
width: 0;
}
.progress-text {
font-size: 12px;
color: #fff;
padding: 0 10px;
position: static;
}
.qystatus {
color: #666;
margin-bottom: 10px;
margin-left: 5px;
}
.success {
padding: 50px 0 60px;
margin-left: -60px;
}
.success p {
margin-top: 20px;
font-size: 16px;
color: #666;
}
.psync_tips{
color: red;
font-size: 15px;
background-color: #fbfbfb;
border: 1px solid #eee;
line-height: 46px;
margin-bottom: 15px;
padding-left: 10px;
}
.psync_tips span{
font-size: 12px;
}
</style>
<div class="migration_api pd15">
<div class="migration_content">
<div class="step_head">
<ul>
<li class="active"><span>1</span><p>填写信息</p></li>
<li><span>2</span><p>检测环境</p></li>
<li><span>3</span><p>选择数据</p></li>
<li><span>4</span><p>一键迁移</p></li>
</ul>
</div>
<div class="step_content">
<div class="pd15 psync_info">
<div class="psync_tips">
<span class="glyphicon glyphicon-alert" style="color: #f39c12; margin-right: 10px;"></span>只需在发送数据服务器安装本软件,请填写<span>『 接收数据服务器 』</span>资料。
<a href="#" target="_blank" class="bt-ico-ask" style="cursor: pointer;">?</a>
</div>
<div class="mtb20">
<span class="panel_setp_span">接收数据的面板地址</span>
<input type="text" class="bt-input-text" name="sync_url" value="" placeholder="接收数据面板地址,如: http://127.0.0.1:8888">
</div>
<div class="mtb20">
<span class="panel_setp_span">接收数据的面板API</span>
<input type="text" class="bt-input-text" name="sync_token" value="" placeholder="接收数据面板API密钥" />
<a href="#" target="_blank" class="btlink ml5">获取API秘钥</a>
</div>
<div class="mtb20">
<span class="panel_setp_span">IP白名单</span>
<span style="height: 32px;line-height: 32px;">必须将本机器IP加入接收数据服务器API的IP白名单,<a href="#" href="javascript:;" target="_blank" class="btlink">如何添加白名单</a></span>
</div>
<div class="mtb20" style="text-align: left;margin-left: 130px;">
<button class="btn btn-success infoNext">下一步</button>
</div>
</div>
<div class="pa15 psync_path" style="margin:0 50px;"></div>
<div class="pa15 psync_data" style="text-align: left;">
<div class="checkbox_conten">
<div class="checkbox_data">
<div class="checkbox_item">
<label class="checkbox_label">
<input type="checkbox" id="sites_All" checked>
<span>网站</span>
</label>
<ul id="sites_li"></ul>
</div>
</div>
<div class="checkbox_data">
<div class="checkbox_item">
<label class="checkbox_label">
<input type="checkbox" id="db_All" checked>
<span>数据库</span>
</label>
<ul id="db_li"></ul>
</div>
</div>
</div>
<div class="line mtb20" style="margin:20px 0 0 50px">
<button class="btn btn-default btn-sm mr20 dataBack">上一步</button>
<button class="btn btn-success btn-sm dataMigrate">一键迁移</button>
</div>
</div>
<div class="pa15 psync_migrate"></div>
</div>
<hr style="margin-top: 5px;" />
<div class="step_footer" style="margin: 5px 0 0 20px;text-align: left;">
<ul class="help-info-text c7 mlr20" style="margin-top: 0px;">
<li>一键迁移过程中是后台执行可以关闭当前窗口</li>
<li>一键迁移迁移数据不涉及原来数据的增删(是将原来数据打包发送)</li>
</ul>
</div>
</div>
</div>
<script type="text/javascript">
resetPluginWinWidth(700);
resetPluginWinWidth(700);
$.getScript( "/plugins/file?name=migration_api&f=js/app.js", function(){
initStep();
});
</script>
+1090
View File
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
{
"sort": 7,
"ps": "[<span style='color:red;'>潜龙勿用</span>]一键迁移,仅网站数据和MySQL数据(仅支持源码安装软件)",
"name": "migration_api",
"title": "一键迁移API",
"shell": "install.sh",
"versions":["1.0"],
"updates":["1.0"],
"tip": "soft",
"checks": "server/migration_api",
"path":"server/migration_api",
"display": 1,
"author": "midoks",
"date": "2022-01-17",
"home": "https://github.com/midoks/mdserver-web",
"type": 0,
"pid": "4"
}
+31
View File
@@ -0,0 +1,31 @@
#!/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=1.0
Install_App(){
mkdir -p $serverPath/migration_api
echo "${VERSION}" > $serverPath/migration_api/version.pl
echo '正在安装脚本文件...' > $install_tmp
}
Uninstall_App()
{
rm -rf $serverPath/migration_api
}
action=$1
if [ "${1}" == 'install' ];then
Install_App
else
Uninstall_App
fi
+333
View File
@@ -0,0 +1,333 @@
function maPostNoMsg(method,args,callback){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(toArrayObject(args));
} else {
_args = JSON.stringify(args);
}
$.post('/plugins/run', {name:'migration_api', func:method, args:_args}, function(data) {
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function maPost(method,args,callback, msg = '正在获取...'){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(toArrayObject(args));
} else {
_args = JSON.stringify(args);
}
var loadT = layer.msg(msg, { icon: 16, time: 0, shade: 0.3 });
$.post('/plugins/run', {name:'migration_api', 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 maAsyncPost(method,args){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(toArrayObject(args));
} else {
_args = JSON.stringify(args);
}
return syncPost('/plugins/run', {name:'migration_api', func:method, args:_args});
}
function maPostCallbak(method, args, callback){
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
var req_data = {};
req_data['name'] = 'migration_api';
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 selectProgress(val){
$('.step_head li').removeClass('active');
$('.step_head li').each(function(){
var v = $(this).find('span').text();
if (val == v){
$(this).addClass('active');
}
});
}
function initStep1(){
var url = $('input[name="sync_url"]').val();
var token = $('input[name="sync_token"]').val();
maPost('step_one',{url:url,token:token}, function(rdata){
var rdata = $.parseJSON(rdata.data);
showMsg(rdata.msg,function(){
if (rdata.status){
initStep2();
}
},{ icon: rdata.status ? 1 : 2 });
},'API校验中...');
}
function initStep2(){
maPost('step_two',{}, function(rdata){
var rdata = $.parseJSON(rdata.data);
showMsg(rdata.msg,function(){
if (rdata.status){
selectProgress(2);
$('.psync_info').hide();
var info = rdata.data;
var body = '<div class="divtable">\
<table class="table table-hover">\
<thead>\
<tr><th style="border-right:1px solid #ddd">服务</th><th>当前服务器</th><th>远程服务器</th></tr>\
</thead>\
<tbody>\
<tr>\
<td style="border-right:1px solid #ddd">网站服务</td>\
<td>'+info['local']['webserver']+'</td>\
<td>'+info['remote']['webserver']+'</td>\
</tr>\
<tr>\
<td style="border-right:1px solid #ddd">安装MySQL</td>\
<td>'+(info['local']['mysql']?'是':'否')+'</td>\
<td>'+(info['remote']['mysql']?'是':'否')+'</td>\
</tr>\
<tr>\
<td style="border-right:1px solid #ddd">安装PHP</td>\
<td>'+(info['local']['php'].join('/'))+'</td>\
<td>'+(info['remote']['php'].join('/')) +'</td>\
</tr>\
<tr>\
<td style="border-right:1px solid #ddd">可用磁盘</td>\
<td>'+info['local']['disk']+'</td>\
<td>'+info['remote']['disk'][0]['size'][0]+'</td>\
</tr>\
</tbody>\
</table>\
</div>';
body += '<div class="line mtb20" style="text-align: left;">\
<button class="btn btn-default btn-sm mr20 pathTestting">重新检测</button>\
<button class="btn btn-default btn-sm mr20 pathBcak">上一步</button>\
<button class="btn btn-success btn-sm psync-next pathNext">下一步</button>\
</div>';
$('.psync_path').html(body);
$('.psync_path').show();
}
},{ icon: rdata.status ? 1 : 2 });
},'检测环境中...');
}
function initStep3(){
maPost('step_three',{}, function(rdata){
var rdata = $.parseJSON(rdata.data);
showMsg(rdata.msg,function(){
if (rdata.status){
selectProgress(3);
var pdata = rdata.data;
var site_li = '';
for (var i = 0; i < pdata.sites.length; i++) {
site_li+='<li>\
<label>\
<input type="checkbox" data-id="'+i+'" id="sites_'+pdata.sites[i]['name']+'" value="'+pdata.sites[i]['name']+'" name="sites" checked="">\
<span title="'+pdata.sites[i]['name']+'">'+pdata.sites[i]['name']+'</span>\
</label>\
</li>';
}
$('#sites_li').html(site_li);
var db_li = '';
for (var i = 0; i < pdata.databases.length; i++) {
db_li+='<li>\
<label>\
<input type="checkbox" data-id="'+i+'" id="sites_'+pdata.databases[i]['name']+'" value="'+pdata.databases[i]['name']+'" name="databases" checked="">\
<span title="'+pdata.databases[i]['name']+'">'+pdata.databases[i]['name']+'</span>\
</label>\
</li>';
}
$('#db_li').html(db_li);
$('.psync_path').hide();
$('.psync_data').show();
}
},{ icon: rdata.status ? 1 : 2 });
});
}
function renderMigrationProgress(){
maPostNoMsg('get_speed',{}, function(rdata){
var rdata = $.parseJSON(rdata.data);
// console.log('speed:',rdata.data);
if (rdata.status){
if (rdata['data']['action'] == 'True'){
var end = '<div class="line">\
<div class="success text-center" style="padding: 10px 0 15px;">\
<p>数据迁移完成,请务必检查数据完整性!</p>\
<p style="font-size: 14px;margin-top:2px;color: #939292;">传输大小: '+toSize(rdata['data']['total_size'])+',耗时: '+rdata['data']['total_time']+',平均速度: '+toSize(rdata['data']['speed'])+'/s</p>\
<p class="mtb15">\
<button class="btn btn-success btn-sm mr5 okBtn">确定完成</button>\
<a class="btn btn-default btn-sm" style="margin-left: 10px;" target="_blank" href="/files/download?filename='+rdata['data']['log_file']+'">迁移日志</a>\
</p>\
</div>\
</div>';
$('.psync_migrate').html(end);
} else{
$('.psync_migrate .action').text(rdata['data']['action']);
$('.psync_migrate .done').text(rdata['data']['done']);
$('.psync_migrate pre').text(rdata['data']['log']);
var p = (rdata['data']['all_speed']/rdata['data']['all_total'])*100;
if (p>100){
p = 100;
}
$('.psync_migrate .progress_info_bar').width(p+'%');
$('.psync_migrate .progress_info').text(p+'%');
renderMigrationProgress();
}
} else{
layer.msg(rdata.msg,{icon:1});
}
});
}
function initStep4(){
var site_checked = '';
$('input[name="sites"]:checked').each(function(){
site_checked += $(this).val()+',';
});
var databases_checked = '';
$('input[name="databases"]:checked').each(function(){
databases_checked+=$(this).val()+',';
});
maPost('step_four',{sites:site_checked,databases:databases_checked}, function(rdata){
var rdata = $.parseJSON(rdata.data);
selectProgress(4);
var progress = '<div style="margin: 0 40px;">\
<div class="line">\
<div style="text-align:left"><span class="action">--</span>\
<span style="margin-left: 20px;" class="done">当前: --</span><img src="/static/img/ing.gif"><a style="position: absolute;right: 40px;" class="btlink psync_close" onclick="migrate.close();">[取消]</a></div>\
<div class="bt-progress" style="border-radius:0;height:20px;line-height:19px">\
<div class="bt-progress-bar progress_info_bar" style="border-radius: 0px; height: 20px; width: 0%;">\
<span class="bt-progress-text progress_info"></span></div>\
</div>\
</div>\
</div>\
<pre style="height: 222px;text-align: left;margin:5px 38px 0;font-size: 12px;line-height: 20px;padding: 10px;background-color: #333;color: #fff;"></pre>\
</div>';
$('.psync_data').hide();
$('.psync_migrate').html(progress);
$('.psync_migrate').show();
renderMigrationProgress();
});
}
function initStep(){
maPost('get_conf',{}, function(rdata){
var rdata = $.parseJSON(rdata.data);
$('input[name="sync_url"]').val(rdata.data['url']);
$('input[name="sync_token"]').val(rdata.data['token']);
});
$('.infoNext').click(function(){
initStep1();
});
// 重新检测按钮
$('.psync_path').on('click', '.pathTestting', function () {
initStep2();
});
$('.psync_path').on('click', '.pathBcak', function(){
$('.psync_path').hide();
$('.psync_info').show();
selectProgress(1);
});
$('.psync_path').on('click', '.pathNext', function(){
initStep3();
});
$('.psync_data').on('click', '.dataBack', function(){
$('.psync_data').hide();
$('.psync_path').show();
selectProgress(2);
});
$('.psync_data').on('click', '.dataMigrate', function(){
initStep4();
});
$('#sites_All').on('click',function(){
var ch = $(this).prop('checked');
$('#sites_li input').prop('checked',ch);
});
$('#db_All').on('click',function(){
var ch = $(this).prop('checked');
$('#db_li input').prop('checked',ch);
});
$('.psync_migrate').on('click', '.okBtn', function(){
$('.psync_migrate').hide();
$('.psync_info').show();
selectProgress(1);
});
}
+1
View File
@@ -65,6 +65,7 @@ binlog-ignore-db = performance_schema
#slave
log-slave-updates
#replicate-do-db
slave_skip_errors=1062
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
+1
View File
@@ -62,6 +62,7 @@ binlog-ignore-db = performance_schema
#slave
log_replica_updates
#replicate-do-db
slave_skip_errors=1062
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
+3
View File
@@ -2682,6 +2682,9 @@ def uninstallPreInspection(version):
if mw.isDebugMode():
return 'ok'
import plugins_api
plugins_api.plugins_api().removeIndex(getPluginName(), version)
return "请手动删除MySQL[{}]<br/> rm -rf {}".format(version, getServerDir())
if __name__ == "__main__":
+1
View File
@@ -66,6 +66,7 @@ binlog-ignore-db = performance_schema
#slave
log-slave-updates
#replicate-do-db
slave_skip_errors=1062
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
+1
View File
@@ -62,6 +62,7 @@ binlog-ignore-db = performance_schema
#slave
log_replica_updates
#replicate-do-db
slave_skip_errors=1062
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
+3
View File
@@ -2639,6 +2639,9 @@ def uninstallPreInspection(version):
if mw.isDebugMode():
return 'ok'
import plugins_api
plugins_api.plugins_api().removeIndex(getPluginName(), version)
return "请手动删除MySQL[{}]<br/> rm -rf {}".format(version, getServerDir())
if __name__ == "__main__":
+1
View File
@@ -70,6 +70,7 @@ log-slave-updates = 1
# Prevent replication from starting automatically with MySQL
#skip-slave-start = 1
#replicate-do-db
slave_skip_errors=1062
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
+1
View File
@@ -72,6 +72,7 @@ log-slave-updates = 1
# Prevent replication from starting automatically with MySQL
#skip-slave-start = 1
#replicate-do-db
slave_skip_errors=1062
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
+1
View File
@@ -73,6 +73,7 @@ binlog-ignore-db = performance_schema
# Prevent replication from starting automatically with MySQL
#skip-slave-start = 1
#replicate-do-db
slave_skip_errors=1062
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
+1
View File
@@ -71,6 +71,7 @@ log_replica_updates = 1
# Prevent replication from starting automatically with MySQL
#skip_replica_start = 1
#replicate-do-db
slave_skip_errors=1062
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
+68 -12
View File
@@ -48,19 +48,20 @@ def getInitDFile():
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':')
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(':')
t = args[i].split(':', 1)
tmp[t[0]] = t[1]
return tmp
@@ -842,12 +843,29 @@ def setDbBackup():
return data[1]
scDir = mw.getRunDir() + '/scripts/backup.py'
cmd = 'python3 ' + scDir + ' database ' + args['name'] + ' 3'
os.system(cmd)
return mw.returnJson(True, 'ok')
# 数据库密码处理
def myPass(act, root):
conf_file = getConf()
mw.execShell("sed -i '/user=root/d' {}".format(conf_file))
mw.execShell("sed -i '/password=/d' {}".format(conf_file))
if act:
mycnf = mw.readFile(conf_file)
src_dump = "[mysqldump]\n"
sub_dump = src_dump + "user=root\npassword=\"{}\"\n".format(root)
if not mycnf:
return False
mycnf = mycnf.replace(src_dump, sub_dump)
if len(mycnf) > 100:
mw.writeFile(conf_file, mycnf)
return True
return True
def importDbExternal():
args = getArgs()
data = checkArgs(args, ['file', 'name'])
@@ -902,11 +920,16 @@ def importDbExternal():
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
sock = getSocketFile()
os.environ["MYSQL_PWD"] = pwd
mysql_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p' + \
pwd + ' ' + name + ' < ' + import_sql
my_cnf = getConf()
myPass(True, pwd)
mysql_cmd = getServerDir() + '/bin/mysql --defaults-file=' + my_cnf + \
' -uroot -p\"' + pwd + '\" -f ' + name + ' < ' + import_sql
# print(mysql_cmd)
rdata = mw.execShell(mysql_cmd)
myPass(False, pwd)
# print(rdata)
if ext != 'sql':
os.remove(import_sql)
@@ -2371,6 +2394,25 @@ def initSlaveStatus(version=''):
return initSlaveStatusSyncUser(version)
def makeSyncUsercmd(u, version=''):
mode = recognizeDbMode()
sql = ''
ip = u['ip']
port = u['port']
username = u['user']
password = u['pass']
if mode == "gtid":
sql = "CHANGE MASTER TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
username + "', MASTER_PASSWORD='" + \
password + "', MASTER_AUTO_POSITION=1"
if version == '8.0':
sql = "CHANGE REPLICATION SOURCE TO SOURCE_HOST='" + ip + "', SOURCE_PORT=" + port + ", SOURCE_USER='" + \
username + "', SOURCE_PASSWORD='" + \
password + "', MASTER_AUTO_POSITION=1"
return sql
def initSlaveStatusSyncUser(version=''):
conn = pSqliteDb('slave_sync_user')
data = conn.field('ip,port,user,pass,mode,cmd').find()
@@ -2393,8 +2435,19 @@ def initSlaveStatusSyncUser(version=''):
if local_mode != mode_name:
return mw.returnJson(False, '同步模式不一致!')
t = db.query(u['cmd'])
# print(t)
if u['cmd'] == '' and local_mode == 'gtid':
sql = makeSyncUsercmd(u, version)
# print(sql)
t = db.query(sql)
else:
if u['cmd'] == '':
return mw.returnJson(False, '经典模式下,必须手写同步命令!')
# print(u['cmd'])
t = db.query(u['cmd'])
isError = isSqlError(t)
if isError:
return isError
db.query("start slave user='{}' password='{}';".format(
u['user'], u['pass']))
return mw.returnJson(True, '初始化成功!')
@@ -2613,7 +2666,7 @@ def doFullSyncUser(version=''):
if not os.path.exists(bak_file):
dump_sql_data = getServerDir() + "/bin/mysqldump " + dmp_option + " --force --opt --default-character-set=utf8 --single-transaction -h" + ip + " -P" + \
port + " -u" + user + " -p" + apass + " " + sync_db + " > " + bak_file
port + " -u" + user + " -p\"" + apass + "\" " + sync_db + " > " + bak_file
mw.execShell(dump_sql_data)
writeDbSyncStatus({'code': 2, 'msg': '本地导入数据...', 'progress': 40})
@@ -2804,6 +2857,9 @@ def uninstallPreInspection(version):
if mw.isDebugMode():
return 'ok'
import plugins_api
plugins_api.plugins_api().removeIndex(getPluginName(), version)
return "请手动删除MySQL[{}]<br/> rm -rf {}".format(version, getServerDir())
if __name__ == "__main__":
+53 -53
View File
@@ -225,6 +225,7 @@ def initTotalInfo():
_name[name] = tmp
total_contents['sites'] = _name
total_contents['start_time'] = str(time.time())
cjson = mw.getJson(total_contents)
mw.writeFile(path_total, cjson)
@@ -324,8 +325,41 @@ def restartWeb():
mw.opWeb('start')
def initDreplace():
def makeDstLua():
root_init_dir = mw.getServerDir() + '/web_conf/nginx/lua/init_by_lua_file'
root_worker_dir = mw.getServerDir() + '/web_conf/nginx/lua/init_worker_by_lua_file'
root_access_dir = mw.getServerDir() + '/web_conf/nginx/lua/access_by_lua_file'
path = getServerDir()
path_tpl = getPluginDir()
waf_common_tpl = path_tpl + "/waf/lua/waf_common.lua"
waf_common_dst = path + "/waf/lua/waf_common.lua"
content = mw.readFile(waf_common_tpl)
content = contentReplace(content)
mw.writeFile(waf_common_dst, content)
waf_init_tpl = path_tpl + "/waf/lua/init_preload.lua"
waf_init_dst = root_init_dir + "/waf_init_preload.lua"
content = mw.readFile(waf_init_tpl)
content = contentReplace(content)
mw.writeFile(waf_init_dst, content)
init_worker_tpl = path_tpl + "/waf/lua/init_worker.lua"
init_worker_dst = root_worker_dir + '/opwaf_init_worker.lua'
content = mw.readFile(init_worker_tpl)
content = contentReplace(content)
mw.writeFile(init_worker_dst, content)
access_file_tpl = path_tpl + "/waf/lua/init.lua"
access_file_dst = root_access_dir + '/opwaf_init.lua'
content = mw.readFile(access_file_tpl)
content = contentReplace(content)
mw.writeFile(access_file_dst, content)
mw.opLuaMakeAll()
def initDreplace():
path = getServerDir()
if not os.path.exists(path + '/waf/lua'):
sdir = getPluginDir() + '/waf'
@@ -348,20 +382,7 @@ def initDreplace():
content['reqfile_path'] = wfDir
mw.writeFile(config, mw.getJson(content))
config = path + "/waf/lua/init.lua"
content = mw.readFile(config)
content = contentReplace(content)
mw.writeFile(config, content)
config_common = path + "/waf/lua/common.lua"
content = mw.readFile(config_common)
content = contentReplace(content)
mw.writeFile(config_common, content)
init_worker = path + "/waf/lua/init_worker.lua"
content = mw.readFile(init_worker)
content = contentReplace(content)
mw.writeFile(init_worker, content)
makeDstLua()
waf_conf = dstWafConf()
if not os.path.exists(waf_conf):
@@ -396,16 +417,6 @@ def status():
def start():
initDreplace()
path = mw.getServerDir() + '/web_conf/nginx/lua/lua.conf'
init_worker_lua = getServerDir() + '/waf/lua/init_worker.lua'
init_lua = getServerDir() + '/waf/lua/init.lua'
conf = mw.readFile(path)
conf = re.sub('init_worker_by_lua_file (.*);',
"init_worker_by_lua_file " + init_worker_lua + ";", conf)
conf = re.sub('access_by_lua_file (.*);',
"access_by_lua_file " + init_lua + ";", conf)
mw.writeFile(path, conf)
import tool_task
tool_task.createBgTask()
@@ -414,15 +425,21 @@ def start():
def stop():
root_init_dir = mw.getServerDir() + '/web_conf/nginx/lua/init_by_lua_file'
root_worker_dir = mw.getServerDir() + '/web_conf/nginx/lua/init_worker_by_lua_file'
root_access_dir = mw.getServerDir() + '/web_conf/nginx/lua/access_by_lua_file'
path = mw.getServerDir() + '/web_conf/nginx/lua/lua.conf'
empty_lua = mw.getServerDir() + '/web_conf/nginx/lua/empty.lua'
conf = mw.readFile(path)
conf = re.sub('init_worker_by_lua_file (.*);',
"init_worker_by_lua_file " + empty_lua + ";", conf)
conf = re.sub('access_by_lua_file (.*);',
"access_by_lua_file " + empty_lua + ";", conf)
mw.writeFile(path, conf)
waf_init_dst = root_init_dir + "/waf_init_preload.lua"
if os.path.exists(waf_init_dst):
os.remove(waf_init_dst)
init_worker_dst = root_worker_dir + '/opwaf_init_worker.lua'
if os.path.exists(init_worker_dst):
os.remove(init_worker_dst)
access_file_dst = root_access_dir + '/opwaf_init.lua'
if os.path.exists(access_file_dst):
os.remove(access_file_dst)
wafconf = dstWafConf()
if os.path.exists(wafconf):
@@ -431,6 +448,8 @@ def stop():
import tool_task
tool_task.removeBgTask()
mw.opLuaMakeAll()
restartWeb()
return 'ok'
@@ -443,26 +462,7 @@ def restart():
def reload():
stop()
path = getServerDir()
path_tpl = getPluginDir()
config = path + "/waf/lua/common.lua"
config_tpl = path_tpl + "/waf/lua/common.lua"
content = mw.readFile(config_tpl)
content = contentReplace(content)
mw.writeFile(config, content)
config = path + "/waf/lua/init_worker.lua"
config_tpl = path_tpl + "/waf/lua/init_worker.lua"
content = mw.readFile(config_tpl)
content = contentReplace(content)
mw.writeFile(config, content)
config = path + "/waf/lua/init.lua"
config_tpl = path_tpl + "/waf/lua/init.lua"
content = mw.readFile(config_tpl)
content = contentReplace(content)
mw.writeFile(config, content)
makeDstLua()
errlog = mw.getServerDir() + "/openresty/nginx/logs/error.log"
mw.execShell('rm -rf ' + errlog)
+13 -1
View File
@@ -1,4 +1,16 @@
{
"hook":[
{
"tag":"site_cb",
"site_cb": {
"title":"网站统计",
"name":"op_waf",
"add":{"func":"reload"},
"update":{"func":"reload"},
"delete":{"func":"reload"}
}
}
],
"title":"OP防火墙",
"tip":"soft",
"name":"op_waf",
@@ -12,5 +24,5 @@
"home":"https://github.com/loveshell/ngx_lua_waf",
"date":"2019-04-21",
"pid": "1",
"versions": ["0.2.4"]
"versions": ["0.2.6"]
}
+7 -8
View File
@@ -24,7 +24,7 @@ else
fi
Install_of(){
Install_App(){
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/source/op_waf
@@ -41,7 +41,9 @@ Install_of(){
cd $serverPath/source/op_waf && tar xvf luarocks-3.5.0.tar.gz
# cd luarocks-3.9.1 && ./configure && make bootstrap
cd luarocks-3.5.0 && ./configure --prefix=$serverPath/op_waf/luarocks --with-lua-include=$serverPath/openresty/luajit/include/luajit-2.1 --with-lua-bin=$serverPath/openresty/luajit/bin
cd luarocks-3.5.0 && ./configure --prefix=$serverPath/op_waf/luarocks \
--with-lua-include=$serverPath/openresty/luajit/include/luajit-2.1 \
--with-lua-bin=$serverPath/openresty/luajit/bin
make -I${serverPath}/openresty/luajit/bin
make install
fi
@@ -85,13 +87,10 @@ Install_of(){
echo 'install ok' > $install_tmp
cd ${rootPath} && python3 ${rootPath}/plugins/op_waf/index.py start
# cd ${rootPath} && python3 ${rootPath}/plugins/op_waf/index.py restart
}
Uninstall_of(){
Uninstall_App(){
cd ${rootPath} && python3 ${rootPath}/plugins/op_waf/index.py stop
if [ "$?" == "0" ];then
@@ -102,7 +101,7 @@ Uninstall_of(){
action=$1
if [ "${1}" == 'install' ];then
Install_of
Install_App
else
Uninstall_of
Uninstall_App
fi
+5 -1
View File
@@ -961,8 +961,12 @@ function wafScreen(){
owPost('waf_srceen', {}, function(data){
var rdata = $.parseJSON(data.data);
var end_time = Date.now();
var cos_time = (end_time/1000) - parseInt(rdata['start_time']);
var cos_day = parseInt(parseInt(cos_time)/86400);
var con = '<div class="wavbox alert alert-success" style="margin-right:16px">总拦截<span>'+rdata.total+'</span>次</div>';
con += '<div class="wavbox alert alert-info" style="margin-right:16px">安全防护<span>0</span>天</div>';
con += '<div class="wavbox alert alert-info" style="margin-right:16px">安全防护<span>'+cos_day+'</span>天</div>';
con += '<div class="screen">\
<div class="line"><span class="name">POST渗透</span><span class="val">'+rdata.rules.post+'</span></div>\
+9
View File
@@ -0,0 +1,9 @@
#!/bin/bash
DST_DIR=/www/server/op_waf
DIS_FILE=${DST_DIR}/cpu.info
CPU_USAGE=`top -bn 1 | fgrep 'Cpu(s)' | awk '{print 100 -$8}' | awk -F . '{print $1}'`
echo $CPU_USAGE
echo $CPU_USAGE > $DIS_FILE
echo "done success!"
+50
View File
@@ -0,0 +1,50 @@
#!/bin/bash
DST_DIR=/www/server/op_waf
DIS_FILE=${DST_DIR}/cpu.info
function GetCpuUsage(){
cpu_info=`cat /proc/stat | head -n 1`
idle_cpu=`echo $cpu_info|awk '{print $2}'`
cpu_total_time=0
for ci in ${cpu_info[@]}; do
if [ "$ci" == "cpu" ];then
continue
else
#echo $ci
cpu_total_time=`expr $cpu_total_time + $ci`
fi
done
#echo "idle_cpu:${idle_cpu}"
#echo "cpu_total_time:${cpu_total_time}"
cpu_percet=$(awk "BEGIN{print ((${cpu_total_time}-${idle_cpu})/${cpu_total_time})*100}")
echo "${cpu_percet}"
return 0
}
# one value detal
getOne=`GetCpuUsage`
CPU_USAGE=`echo $getOne | awk -F . '{print $1}'`
echo "cpu usage:${CPU_USAGE}"
echo $CPU_USAGE > $DIS_FILE
echo "done success!"
# two value compare
# getOne=`GetCpuUsage`
# echo "getOne:$getOne"
# sleep 1
# getTwo=`GetCpuUsage`
# echo "getTwo:$getTwo"
# cpu_percet_calc=$(awk "BEGIN{print (${getOne}+${getTwo})/2}")
# echo "cpu_percet_calc:${cpu_percet_calc}"
# #echo '0.61212' | awk -F . '{print $1}'
# CPU_USAGE=`echo $cpu_percet_calc | awk -F . '{print $1}'`
# echo "cpu usage:${CPU_USAGE}"
# echo $CPU_USAGE > $DIS_FILE
# echo "done success!"
+2 -1
View File
@@ -26,4 +26,5 @@ fi
# $RUN_CMD --stap --shdict 'limit 10m' test_find_server_name.lua
# $RUN_CMD test_rand.lua
$RUN_CMD test_ffi_time.lua
# $RUN_CMD test_ffi_time.lua
$RUN_CMD test_get_cpu.lua
+69
View File
@@ -0,0 +1,69 @@
-- cd /www/server/mdserver-web/plugins/op_waf/t/bench && bash bench.sh
local function target()
ngx.re.find("hello, world.", [[\w+\.]], "jo")
end
for i = 1, 100 do
target()
end
local function file_exists(path)
local file = io.open(path, "rb")
if file then file:close() end
return file ~= nil
end
-- 以上为预热操作
collectgarbage()
local json = require "cjson"
local ngx_re = require "ngx.re"
local function data_split(self, str,reps )
local rsList = {}
string.gsub(str,'[^'..reps..']+',function(w)
table.insert(rsList,w)
end)
return rsList
end
local function get_cpu_stat()
local cpu_total = 0
local fp = io.open('/proc/stat','r')
local cpu_line = fp:read()
fp:close()
local list = ngx_re.split(cpu_line," ")
table.remove(list,1)
table.remove(list,1)
local idie = list[4]
for i,v in pairs(list)
do
cpu_total = cpu_total + v
end
local use_percent = tonumber(100-(idie/cpu_total)*100)
return cpu_total,idie,use_percent
end
local function get_cpu_percent()
local cpu_total,idie,use_percent = get_cpu_stat()
ngx.sleep(2)
local cpu_total2,idie2,use_percent2 = get_cpu_stat()
local cpu_usage_percent = tonumber(100-(((idie2-idie)/(cpu_total2-cpu_total))*100))
ngx.say("cpu_usage_percent:"..cpu_usage_percent)
return cpu_usage_percent
end
ngx.update_time()
local begin = ngx.now()
local N = 1e1
for i = 1, N do
get_cpu_stat()
end
ngx.update_time()
ngx.say("test_get_cpu elapsed: ", (ngx.now() - begin))
+86 -20
View File
@@ -1,6 +1,46 @@
#!/bin/sh
export PATH=$PATH:/opt/stap/bin:/opt/stapxx
# cd /www/server/mdserver-web/plugins/op_waf/t && bash ngx_debug.sh lua ok
# cd /www/server/mdserver-web/plugins/op_waf/t && bash ngx_debug.sh c ok
if [ ${_os} == "Darwin" ]; then
OSNAME='macos'
elif grep -Eq "openSUSE" /etc/*-release; then
OSNAME='opensuse'
zypper refresh
zypper install cron wget curl zip unzip
elif grep -Eq "FreeBSD" /etc/*-release; then
OSNAME='freebsd'
elif grep -Eqi "CentOS" /etc/issue || grep -Eq "CentOS" /etc/*-release; then
OSNAME='rhel'
yum install -y wget curl zip unzip tar crontabs
elif grep -Eqi "Fedora" /etc/issue || grep -Eq "Fedora" /etc/*-release; then
OSNAME='fedora'
yum install -y wget curl zip unzip tar crontabs
elif grep -Eqi "Rocky" /etc/issue || grep -Eq "Rocky" /etc/*-release; then
OSNAME='rhel'
yum install -y wget curl zip unzip tar crontabs
elif grep -Eqi "AlmaLinux" /etc/issue || grep -Eq "AlmaLinux" /etc/*-release; then
OSNAME='rhel'
yum install -y wget curl zip unzip tar crontabs
elif grep -Eqi "Amazon Linux" /etc/issue || grep -Eq "Amazon Linux" /etc/*-release; then
OSNAME='amazon'
yum install -y wget curl zip unzip tar crontabs
elif grep -Eqi "Debian" /etc/issue || grep -Eq "Debian" /etc/os-release; then
OSNAME='debian'
apt update -y
apt install -y wget curl zip unzip tar cron
elif grep -Eqi "Ubuntu" /etc/issue || grep -Eq "Ubuntu" /etc/os-release; then
OSNAME='ubuntu'
apt update -y
apt install -y wget curl zip unzip tar cron
else
OSNAME='unknow'
fi
# https://moonbingbing.gitbooks.io/openresty-best-practices/content/flame_graph/install.html
# apt install elfutils
# sudo apt-get install -y systemtap gcc
@@ -23,7 +63,7 @@ then
exit
fi
pid=`ps -ef|grep openresty | grep -v grep | awk '{print $2}'`
pids=`ps -ef|grep nginx | grep -v grep | awk '{print $2}'`
name=$2
@@ -33,7 +73,13 @@ name=$2
# apt install -y kernel-debuginfo-common kernel-debuginfo
# apt install -y kernel-*
if [ "$OSNAME" == "debian" ];then
apt install -y systemtap
apt-get install -y build-essential
apt-get install -y linux-headers-$(uname -r)
elif [ "$OSNAME" == "centos" ];then
yum install -y kernel-devel-$(uname -r)
fi
# /opt/stapxx/samples/lj-lua-stacks.sxx --arg time=5 --skip-badvars -x 45266 > tmp.bt
@@ -58,25 +104,45 @@ if [ ! -d /opt/FlameGraph ];then
cd /opt && git clone https://github.com/brendangregg/FlameGraph
fi
if [ $1 == "lua" ]; then
# /opt/openresty-systemtap-toolkit/ngx-sample-lua-bt -p 377452 --luajit20 -t 30 >temp.bt
/opt/openresty-systemtap-toolkit/ngx-sample-lua-bt -p $pid --luajit20 -t 30 >temp.bt
# /opt/openresty-systemtap-toolkit/fix-lua-bt temp.bt >t1.bt
/opt/openresty-systemtap-toolkit/fix-lua-bt temp.bt >${name}.bt
elif [ $1 == "c" ]; then
# /opt/openresty-systemtap-toolkit/sample-bt -p 496435 -t 10 -u > t2.bt
/opt/openresty-systemtap-toolkit/sample-bt -p $pid -t 10 -u > ${name}.bt
else
echo "type is only lua/c"
exit
fi
for pid in ${pids[@]}; do
echo "strace:$pid"
if [ $1 == "lua" ]; then
# --without-luajit-gc64 | lua 模式编译时需要使用此参数
/opt/openresty-systemtap-toolkit/ngx-sample-lua-bt -p $pid --luajit20 -t 30 >temp.bt
/opt/openresty-systemtap-toolkit/fix-lua-bt temp.bt >${name}_${pid}.bt
elif [ $1 == "c" ]; then
/opt/openresty-systemtap-toolkit/sample-bt -p $pid -t 10 -u > ${name}_${pid}.bt
else
echo "type is only lua/c"
exit
fi
/opt/FlameGraph/stackcollapse-stap.pl ${name}_${pid}.bt >${name}_${pid}.cbt
/opt/FlameGraph/flamegraph.pl ${name}_${pid}.cbt >${name}_${pid}.svg
rm -f temp.bt ${name}_${pid}.bt ${name}_${pid}.cbt
echo "strace:$pid, end!"
echo "${name}_${pid}.svg -- make ok"
done
# if [ $1 == "lua" ]; then
# # /opt/openresty-systemtap-toolkit/ngx-sample-lua-bt -p 377452 --luajit20 -t 30 >temp.bt
# /opt/openresty-systemtap-toolkit/ngx-sample-lua-bt -p $pid --luajit20 -t 30 >temp.bt
# # /opt/openresty-systemtap-toolkit/fix-lua-bt temp.bt >t1.bt
# /opt/openresty-systemtap-toolkit/fix-lua-bt temp.bt >${name}.bt
# elif [ $1 == "c" ]; then
# # /opt/openresty-systemtap-toolkit/sample-bt -p 496435 -t 10 -u > t2.bt
# /opt/openresty-systemtap-toolkit/sample-bt -p $pid -t 10 -u > ${name}.bt
# else
# echo "type is only lua/c"
# exit
# fi
# # debuginfo-install kernel-3.10.0-1160.80.1.el7.x86_64
# # /opt/FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
# # /opt/FlameGraph/flamegraph.pl perf.folded > perf.svg
# /opt/FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
# /opt/FlameGraph/flamegraph.pl perf.folded > perf.svg
/opt/FlameGraph/stackcollapse-stap.pl ${name}.bt >${name}.cbt
/opt/FlameGraph/flamegraph.pl ${name}.cbt >${name}.svg
rm -f temp.bt ${name}.bt ${name}.cbt
# /opt/FlameGraph/stackcollapse-stap.pl ${name}.bt >${name}.cbt
# /opt/FlameGraph/flamegraph.pl ${name}.cbt >${name}.svg
# rm -f temp.bt ${name}.bt ${name}.cbt
+22 -6
View File
@@ -54,7 +54,9 @@ def createBgTask():
"period": "minute-n",
"minute-n": "1",
}
createBgTaskByName(getPluginName(), args)
if mw.isAppleSystem():
createBgTaskByName(getPluginName(), args)
def createBgTaskByName(name, args):
@@ -97,8 +99,14 @@ logs_file=$plugin_path/${rname}.log
''' % (mw_dir, name, getServerDir(), getPluginDir())
cmd += 'echo "★【`date +"%Y-%m-%d %H:%M:%S"`】 STSRT★" >> $logs_file' + "\n"
cmd += 'echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" >> $logs_file' + "\n"
cmd += 'echo "cd $mw_dir && source bin/activate && python3 $script_path/tool_task.py run >> $logs_file 2>&1"' + "\n"
cmd += 'cd $mw_dir && source bin/activate && python3 $script_path/tool_task.py run >> $logs_file 2>&1' + "\n"
if mw.isAppleSystem():
cmd += 'echo "cd $mw_dir && source bin/activate && python3 $script_path/tool_task.py run >> $logs_file 2>&1"' + "\n"
cmd += 'cd $mw_dir && source bin/activate && python3 $script_path/tool_task.py run >> $logs_file 2>&1' + "\n"
else:
cmd += 'echo "cd $mw_dir && source bin/activate && bash $script_path/shell/cpu_usage_file.sh >> $logs_file 2>&1"' + "\n"
cmd += 'cd $mw_dir && source bin/activate && bash $script_path/shell/cpu_usage.sh >> $logs_file 2>&1' + "\n"
cmd += 'echo "【`date +"%Y-%m-%d %H:%M:%S"`】 END★" >> $logs_file' + "\n"
cmd += 'echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" >> $logs_file' + "\n"
@@ -128,6 +136,9 @@ logs_file=$plugin_path/${rname}.log
def removeBgTask():
if not mw.isAppleSystem():
return False
cfg_list = getConfigData()
for x in range(len(cfg_list)):
cfg = cfg_list[x]
@@ -147,10 +158,15 @@ def removeBgTask():
def getCpuUsed():
import psutil
used = psutil.cpu_percent(interval=1)
path = getServerDir() + "/cpu.info"
mw.writeFile(path, str(int(used)))
if mw.isAppleSystem():
import psutil
used = psutil.cpu_percent(interval=1)
mw.writeFile(path, str(int(used)))
else:
cmd = "top -bn 1 | fgrep 'Cpu(s)' | awk '{print 100 -$8}' | awk -F . '{print $1}'"
data = mw.execShell(cmd)
mw.writeFile(path, str(int(data[0].strip())))
def run():
+20 -13
View File
@@ -1,19 +1,8 @@
local waf_root = "{$WAF_ROOT}"
local waf_cpath = waf_root.."/waf/lua/?.lua;"..waf_root.."/waf/conf/?.lua;"..waf_root.."/waf/html/?.lua;"
local waf_sopath = waf_root.."/waf/conf/?.so;"
if not package.path:find(waf_cpath) then
package.path = waf_cpath .. package.path
end
if not package.cpath:find(waf_sopath) then
package.cpath = waf_sopath .. package.cpath
end
local json = require "cjson"
local ngx_match = ngx.re.find
local __WAF = require "common"
local __WAF = require "waf_common"
-- print(json.encode(__C))
local C = __WAF:getInstance()
@@ -47,7 +36,8 @@ local url_rules = require "rule_url"
local url_white_rules = require "rule_url_white"
local server_name = string.gsub(C:get_sn(config_domains),'_','.')
-- local server_name = string.gsub(C:get_sn(config_domains),'_','.')
local server_name = C:get_sn(config_domains)
local function initParams()
local data = {}
@@ -533,41 +523,58 @@ 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
if X_Forwarded() then return true end
-- C:D("X_Forwarded")
if post_X_Forwarded() then return true end
-- C:D("post_X_Forwarded")
if url_ext() then return true end
-- C:D("url_ext")
if post_data() then return true end
-- C:D("post_data")
end
end
+11
View File
@@ -0,0 +1,11 @@
local waf_root = "{$WAF_ROOT}"
local waf_cpath = waf_root.."/waf/lua/?.lua;"..waf_root.."/waf/conf/?.lua;"..waf_root.."/waf/html/?.lua;"
local waf_sopath = waf_root.."/waf/conf/?.so;"
if not package.path:find(waf_cpath) then
package.path = waf_cpath .. package.path
end
if not package.cpath:find(waf_sopath) then
package.cpath = waf_sopath .. package.cpath
end
+40 -20
View File
@@ -1,38 +1,58 @@
local waf_root = "{$WAF_ROOT}"
local waf_cpath = waf_root.."/waf/lua/?.lua;"..waf_root.."/waf/conf/?.lua;"..waf_root.."/waf/html/?.lua;"
local waf_sopath = waf_root.."/waf/conf/?.so;"
if not package.path:find(waf_cpath) then
package.path = waf_cpath .. package.path
end
-- local waf_cpath = waf_root.."/waf/lua/?.lua;"..waf_root.."/waf/conf/?.lua;"..waf_root.."/waf/html/?.lua;"
-- local waf_sopath = waf_root.."/waf/conf/?.so;"
-- if not package.path:find(waf_cpath) then
-- package.path = waf_cpath .. package.path
-- end
if not package.cpath:find(waf_sopath) then
package.cpath = waf_sopath .. package.cpath
end
-- if not package.cpath:find(waf_sopath) then
-- package.cpath = waf_sopath .. package.cpath
-- end
local json = require "cjson"
local __C = require "common"
local C = __C:getInstance()
local __WAF_C = require "waf_common"
local WAF_C = __WAF_C:getInstance()
local function timer_stats_total_log(premature)
C:timer_stats_total()
local waf_config = require "waf_config"
local waf_site_config = require "waf_site"
WAF_C:setConfData(waf_config, waf_site_config)
WAF_C:setDebug(true)
-- C:D("init worker"..tostring(ngx.worker.id()))
local function waf_timer_stats_total_log(premature)
WAF_C:timer_stats_total()
end
local waf_clean_expire_data = function(premature)
WAF_C:clean_log()
end
ngx.shared.waf_limit:set("cpu_usage", 0, 10)
function timer_every_get_cpu(premature)
local cpu_percent = C:read_file_body(waf_root.."/cpu.info")
if cpu_percent then
ngx.shared.waf_limit:set("cpu_usage", tonumber(cpu_percent), 10)
function waf_timer_every_get_cpu(premature)
if WAF_C:file_exists('/proc/stat') then
local lua_cpu_percent = WAF_C:get_cpu_percent()
-- WAF_C:D("lua_cpu_percent:"..tostring(lua_cpu_percent))
ngx.shared.waf_limit:set("cpu_usage", math.floor(lua_cpu_percent), 10)
else
ngx.shared.waf_limit:set("cpu_usage", 0, 10)
local cpu_percent = WAF_C:read_file_body(waf_root.."/cpu.info")
-- WAF_C:D("cpu_usage:"..tostring(cpu_percent ))
if cpu_percent then
ngx.shared.waf_limit:set("cpu_usage", tonumber(cpu_percent), 10)
else
ngx.shared.waf_limit:set("cpu_usage", 0, 10)
end
end
end
if 0 == ngx.worker.id() then
ngx.timer.every(5, timer_every_get_cpu)
if ngx.worker.id() == 0 then
ngx.timer.every(6, waf_timer_every_get_cpu)
-- 异步执行
ngx.timer.every(3, timer_stats_total_log)
ngx.timer.every(3, waf_timer_stats_total_log)
ngx.timer.every(10, waf_clean_expire_data)
WAF_C:cron()
end
@@ -17,7 +17,9 @@ local mt = { __index = _M }
local json = require "cjson"
local sqlite3 = require "lsqlite3"
local ngx_re = require "ngx.re"
local ngx_match = ngx.re.find
local debug_mode = false
local cpath = waf_root.."/waf/"
@@ -41,42 +43,25 @@ function _M.new(self)
end
function _M.getInstance(self)
if rawget(self, "instance") == nil then
rawset(self, "instance", self:new())
-- function _M.getInstance(self)
-- if rawget(self, "instance") == nil then
-- rawset(self, "instance", self.new())
-- end
-- assert(self.instance ~= nil)
-- return self.instance
-- end
if 0 == ngx.worker.id() then
self:cron()
end
function _M.getInstance(self)
if self.instance == nil then
self.instance = self:new()
end
assert(self.instance ~= nil)
return self.instance
end
function _M.initDB(self)
local path = log_dir .. "/waf.db"
db, err = sqlite3.open(path)
if err then
self:D("initDB err:"..tostring(err))
return nil
end
db:exec([[PRAGMA synchronous = 0]])
db:exec([[PRAGMA cache_size = 8000]])
db:exec([[PRAGMA page_size = 32768]])
db:exec([[PRAGMA journal_mode = wal]])
db:exec([[PRAGMA journal_size_limit = 1073741824]])
return db
end
-- 后台任务
function _M.cron(self)
local timer_every_get_data = function(premature)
self:clean_log()
end
ngx.timer.every(10, timer_every_get_data)
local timer_every_import_data = function(premature)
local llen, _ = ngx.shared.waf_limit:llen('waf_limit_logs')
@@ -91,7 +76,6 @@ function _M.cron(self)
local stmt2 = db:prepare[[INSERT INTO logs(time, ip, domain, server_name, method, status_code, uri, user_agent, rule_name, reason)
VALUES(:time, :ip, :domain, :server_name, :method, :status_code, :uri, :user_agent, :rule_name, :reason)]]
if not stmt2 then
self:D("waf timer db:prepare fail!:"..tostring(stmt2))
return false
@@ -136,6 +120,22 @@ function _M.cron(self)
ngx.timer.every(0.5, timer_every_import_data)
end
function _M.initDB(self)
local path = log_dir .. "/waf.db"
db, err = sqlite3.open(path)
if err then
self:D("initDB err:"..tostring(err))
return nil
end
db:exec([[PRAGMA synchronous = 0]])
db:exec([[PRAGMA cache_size = 8000]])
db:exec([[PRAGMA page_size = 32768]])
db:exec([[PRAGMA journal_mode = wal]])
db:exec([[PRAGMA journal_size_limit = 1073741824]])
return db
end
function _M.clean_log(self)
local db = self:initDB()
@@ -392,6 +392,12 @@ function _M.read_file(self, name)
return data
end
function _M.file_exists(self,path)
local file = io.open(path, "rb")
if file then file:close() end
return file ~= nil
end
function _M.select_rule(self, rules)
if not rules then return {} end
@@ -761,6 +767,34 @@ function _M.is_key(self, arr, key)
return false
end
function _M.get_cpu_stat(self)
local cpu_total = 0
local fp = io.open('/proc/stat','r')
local cpu_line = fp:read()
fp:close()
local list = ngx_re.split(cpu_line," ")
table.remove(list,1)
table.remove(list,1)
local idie = list[4]
for i,v in pairs(list)
do
cpu_total = cpu_total + v
end
local use_percent = tonumber(100-(idie/cpu_total)*100)
return cpu_total,idie,use_percent
end
function _M.get_cpu_percent(self)
local cpu_total,idie,use_percent = self:get_cpu_stat()
ngx.sleep(2)
local cpu_total2,idie2,use_percent2 = self:get_cpu_stat()
local cpu_usage_percent = tonumber(100-(((idie2-idie)/(cpu_total2-cpu_total))*100))
return cpu_usage_percent
end
function _M.return_post_data(self)
if method ~= "POST" then return false end
+1 -1
View File
@@ -1 +1 @@
[[[127, 0, 0, 1], [127, 0, 0, 255]]]
[[[127,0,0,1], [127, 0, 0, 255]]]
+5 -2
View File
@@ -3,8 +3,11 @@ lua_package_cpath "{$SERVER_PATH}/web_conf/nginx/lua/?.so;{$SERVER_PATH}/openres
lua_code_cache on;
#waf
#init_by_lua_file
init_by_lua_file {$SERVER_PATH}/web_conf/nginx/lua/empty.lua;
#init_worker_by_lua
init_worker_by_lua_file {$SERVER_PATH}/web_conf/nginx/lua/empty.lua;
#waf && webstats need;
#access_by_lua_file
access_by_lua_file {$SERVER_PATH}/web_conf/nginx/lua/empty.lua;
+6 -5
View File
@@ -149,16 +149,17 @@ def confReplace():
mw.execShell('mkdir -p ' + lua_conf_dir)
lua_conf = lua_conf_dir + '/lua.conf'
if not os.path.exists(lua_conf):
lua_conf_tpl = getPluginDir() + '/conf/lua.conf'
lua_content = mw.readFile(lua_conf_tpl)
lua_content = lua_content.replace('{$SERVER_PATH}', service_path)
mw.writeFile(lua_conf, lua_content)
lua_conf_tpl = getPluginDir() + '/conf/lua.conf'
lua_content = mw.readFile(lua_conf_tpl)
lua_content = lua_content.replace('{$SERVER_PATH}', service_path)
mw.writeFile(lua_conf, lua_content)
empty_lua = lua_conf_dir + '/empty.lua'
if not os.path.exists(empty_lua):
mw.writeFile(empty_lua, '')
mw.opLuaMakeAll()
# 静态配置
php_conf = mw.getServerDir() + '/web_conf/php/conf'
if not os.path.exists(php_conf):
+3 -1
View File
@@ -2,6 +2,8 @@
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# cd /www/server/mdserver-web/plugins/openresty && bash install.sh install 1.21.4.1
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
@@ -57,11 +59,11 @@ Install_openresty()
mkdir -p ${openrestyDir}
echo '正在安装脚本文件...' > $install_tmp
# 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
fi
cd ${openrestyDir} && tar -zxvf openresty-${VERSION}.tar.gz
# --with-openssl=$serverPath/source/lib/openssl-1.0.2q
+1
View File
@@ -83,6 +83,7 @@ if [ "${action}" == "install" ] && [ -d ${serverPath}/php-apt/${type} ];then
# 安装通用扩展
echo "install PHP-APT[${type}] extend start"
cd ${rootPath}/plugins/php-apt/versions && bash common.sh ${type:0:1}.${type:1:2} install curl
cd ${rootPath}/plugins/php-apt/versions && bash common.sh ${type:0:1}.${type:1:2} install gd
cd ${rootPath}/plugins/php-apt/versions && bash common.sh ${type:0:1}.${type:1:2} install iconv
cd ${rootPath}/plugins/php-apt/versions && bash common.sh ${type:0:1}.${type:1:2} install exif
+13
View File
@@ -233,6 +233,19 @@
"shell": "xml.sh",
"check": "xml"
},
{
"name": "curl",
"versions": [
"74",
"80",
"81",
"82"
],
"type": "通用扩展",
"msg": "通用CURL库!",
"shell": "curl.sh",
"check": "curl"
},
{
"name": "gd",
"versions": [
+1 -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.25
version=8.0.27
PHP_VER=80
Install_php()
{
+1 -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.12
version=8.1.15
PHP_VER=81
Install_php()
{
+1 -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.0
version=8.2.2
PHP_VER=82
Install_php()
{
+3 -2
View File
@@ -47,7 +47,8 @@ Install_phpmyadmin()
mkdir -p ${serverPath}/phpmyadmin
mkdir -p ${serverPath}/source/phpmyadmin
echo "${1}" > ${serverPath}/phpmyadmin/version.pl
VER=$1
FDIR=phpMyAdmin-${VER}-all-languages
@@ -67,7 +68,7 @@ Install_phpmyadmin()
cd $serverPath/phpmyadmin/ && mv $FDIR phpmyadmin
echo "${1}" > ${serverPath}/phpmyadmin/version.pl
echo '安装完成' > $install_tmp
cd ${rootPath} && python3 ${rootPath}/plugins/phpmyadmin/index.py start
-1
View File
@@ -26,7 +26,6 @@ AutoRename no
AnonymousCantUpload no
MaxDiskUsage 99
CustomerProof yes
PassivePortRange 48000 50000
PIDFile {$SERVER_PATH}/pureftp/etc/pure-ftpd.pid
PureDB {$SERVER_PATH}/pureftp/etc/pureftpd.pdb
+5
View File
@@ -9,6 +9,11 @@ serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
if [ -f ${rootPath}/bin/activate ];then
source ${rootPath}/bin/activate
fi
sysName=`uname`
echo "use system: ${sysName}"
+5 -2
View File
@@ -54,13 +54,16 @@ def getArgs():
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':')
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
+4
View File
@@ -16,6 +16,10 @@ bash ${rootPath}/scripts/getos.sh
OSNAME=`cat ${rootPath}/data/osname.pl`
if [ -f ${rootPath}/bin/activate ];then
source ${rootPath}/bin/activate
fi
if id www &> /dev/null ;then
echo "www uid is `id -u www`"
echo "www shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
+127
View File
@@ -0,0 +1,127 @@
#
# Discuz Sphinx Config File
#
indexer
{
mem_limit = 32M
write_buffer = 64M
}
searchd
{
listen = 9312
listen = 9306:mysql41
log = {$SERVER_APP}/index/searchd.log
query_log = {$SERVER_APP}/index/query.log
read_timeout = 5
max_children = 0
pid_file = {$SERVER_APP}/index/searchd.pid
seamless_rotate = 1
preopen_indexes = 1
unlink_old = 1
#workers = threads # for RT to work
binlog_path = {$SERVER_APP}/index/binlog
}
source pre_forum_thread
{
type = mysql
sql_host = 127.0.0.1
sql_user = bbs
sql_pass = bbs
sql_db = bbs
sql_port = 3306
sql_query_pre = SET NAMES UTF8
sql_query_pre = SET SESSION query_cache_type=OFF
sql_query_pre = REPLACE INTO bbs_common_sphinxcounter SELECT 1, MAX(tid) FROM bbs_forum_thread
sql_query = SELECT t.tid as id,t.tid,t.subject,t.digest,t.displayorder,t.authorid,t.lastpost,t.special \
FROM bbs_forum_thread AS t WHERE t.tid>=$start AND t.tid<=$end
sql_query_range = SELECT (SELECT MIN(tid) FROM bbs_forum_thread),maxid FROM bbs_common_sphinxcounter WHERE indexid=1
sql_range_step = 5000
sql_attr_uint = tid
sql_attr_uint = digest
sql_attr_uint = displayorder
sql_attr_uint = authorid
sql_attr_uint = special
sql_attr_timestamp =lastpost
}
index pre_forum_thread
{
source = pre_forum_thread
path = {$SERVER_APP}/index/db/pre_forum_thread/index
min_word_len = 2
html_strip = 1
ngram_len = 1
ngram_chars = U+3000..U+2FA1F
}
# threads_minute
source pre_forum_thread_minute : pre_forum_thread
{
sql_query_pre = SET NAMES UTF8
sql_query_pre = SET SESSION query_cache_type=OFF
sql_query_range = SELECT maxid-1,(SELECT MAX(tid) FROM bbs_forum_thread) FROM bbs_common_sphinxcounter WHERE indexid=1
}
# threads_minute
index pre_forum_thread_minute : pre_forum_thread
{
source = pre_forum_thread_minute
path = {$SERVER_APP}/index/db/pre_forum_thread/pre_forum_thread_minute
}
#posts
source pre_forum_post : pre_forum_thread
{
type = mysql
sql_query_pre =
sql_query_pre = SET NAMES UTF8
sql_query_pre = SET SESSION query_cache_type=OFF
sql_query_pre = REPLACE INTO bbs_common_sphinxcounter SELECT 2, MAX(pid) FROM bbs_forum_post
sql_query = SELECT p.pid AS id,p.tid,p.subject,p.message,t.digest,t.displayorder,t.authorid,t.lastpost,t.special \
FROM bbs_forum_post AS p LEFT JOIN bbs_forum_thread AS t USING(tid) where p.pid >=$start and p.pid <=$end \
AND p.first=1
sql_query_range = SELECT (SELECT MIN(pid) FROM bbs_forum_post),maxid FROM bbs_common_sphinxcounter WHERE indexid=2
sql_range_step = 5000
sql_attr_uint = tid
sql_attr_uint = digest
sql_attr_uint= displayorder
sql_attr_uint = authorid
sql_attr_uint = special
sql_attr_timestamp = lastpost
}
#posts
index pre_forum_post
{
source = pre_forum_post
path = {$SERVER_APP}/index/db/pre_forum_thread/pre_forum_post
min_word_len = 2
html_strip = 1
ngram_len = 1
ngram_chars = U+3000..U+2FA1F
}
#pre_forum_post_minute
source pre_forum_post_minute : pre_forum_post
{
sql_query_pre = SET NAMES UTF8
sql_query_pre = SET SESSION query_cache_type=OFF
sql_query_range = SELECT maxid-1,(SELECT MAX(pid) FROM bbs_forum_post) FROM bbs_common_sphinxcounter WHERE indexid=2
}
#pre_forum_post_minute
index pre_forum_post_minute : pre_forum_post
{
source = pre_forum_thread
path = {$SERVER_APP}/index/db/pre_forum_thread/pre_forum_post_minute
}
+5 -2
View File
@@ -34,13 +34,16 @@ def getArgs():
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':')
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
+26 -22
View File
@@ -25,7 +25,7 @@ class App():
self.__host_dir = self.getServerDir() + '/host'
if not os.path.exists(self.__host_dir):
os.makedirs(self.__host_dir)
mw.execShell('mkdir -p ' + self.__host_dir)
def getPluginName(self):
return 'webssh'
@@ -43,13 +43,16 @@ class App():
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':')
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(self, data, ck=[]):
@@ -110,7 +113,7 @@ class App():
def getSshInfo(self, file):
rdata = mw.readFile(file)
destr = mw.deCrypt('mdserver-web', rdata)
destr = mw.enDoubleCrypt('mdserver-web', rdata)
return json.loads(destr)
def get_server_by_host(self):
@@ -142,24 +145,25 @@ class App():
def get_server_list(self):
host_list = []
for name in os.listdir(self.__host_dir):
info_file = self.__host_dir + '/' + name + '/info.json'
if not os.path.exists(info_file):
continue
try:
info_tmp = self.getSshInfo(info_file)
host_info = {}
host_info['host'] = name
host_info['port'] = info_tmp['port']
host_info['ps'] = info_tmp['ps']
# host_info['sort'] = int(info_tmp['sort'])
except Exception as e:
print(e)
# if os.path.exists(info_file):
# os.remove(info_file)
# continue
if os.path.exists(self.__host_dir):
for name in os.listdir(self.__host_dir):
info_file = self.__host_dir + '/' + name + '/info.json'
if not os.path.exists(info_file):
continue
try:
info_tmp = self.getSshInfo(info_file)
host_info = {}
host_info['host'] = name
host_info['port'] = info_tmp['port']
host_info['ps'] = info_tmp['ps']
# host_info['sort'] = int(info_tmp['sort'])
except Exception as e:
print(e)
# if os.path.exists(info_file):
# os.remove(info_file)
# continue
host_list.append(host_info)
host_list.append(host_info)
host_list = sorted(host_list, key=lambda x: x['host'], reverse=False)
return mw.returnJson(True, 'ok!', host_list)
@@ -199,7 +203,7 @@ class App():
if not os.path.exists(dst_host_dir):
os.makedirs(dst_host_dir)
enstr = mw.enCrypt('mdserver-web', json.dumps(info))
enstr = mw.enDoubleCrypt('mdserver-web', json.dumps(info))
mw.writeFile(dst_host_dir + '/info.json', enstr)
return mw.returnJson(True, '添加成功!')
+8
View File
@@ -9,6 +9,14 @@
"css_path":"menu/index.css",
"js_path":"js/webssh.js"
}
},
{
"tag":"global_static",
"global_static": {
"title":"终端管理",
"name":"webssh",
"css_path":"menu/ico.css"
}
}
],
"id":3,
+10
View File
@@ -0,0 +1,10 @@
/* menu start */
.menu .menu_plugin_webssh {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAMBJREFUeNpiYKAQMM6cOVMASBuQozk9Pf0AC5AuAOJ6cgwAWt7IhMQvRKIfAPEEYgxhQWL3o9EFpBgwAeifQhKdD7YI5oWPUMEEmAQR4COyATBwAIgdgIacB2IFYkxhQouWB0BsCA3E86QGIsxvDSBXgGIDSxr5ALTgAk4XADWAQt4fiB2BChcAaQVoGoHheLwuAGqagBz/UNsciQ4DEgE/zAUfQM4DOt+eRANAYTMRZADIrxfIdMUFSnMzA0CAAQD0hjqnYxWD2gAAAABJRU5ErkJggg==");
}
.menu .current .menu_plugin_webssh:hover {
background-image: url("data:image/gif;base64,R0lGODlhEAAQAMQXAJ6ipUFITySRPIiMkDFRQuXm5jJKQy1kQCGeOzBXQSl3PiWLPVhfZSxrQCpxP9na2yeEPTREQ8LExmRqb5OXm/Hx8TU9RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ1IDc5LjE2MzQ5OSwgMjAxOC8wOC8xMy0xNjo0MDoyMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjMyQjYwMTU3OTA2QTExRUJCN0NFQUUwQjRDMzM4RDJDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjMyQjYwMTU4OTA2QTExRUJCN0NFQUUwQjRDMzM4RDJDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MzJCNjAxNTU5MDZBMTFFQkI3Q0VBRTBCNEMzMzhEMkMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MzJCNjAxNTY5MDZBMTFFQkI3Q0VBRTBCNEMzMzhEMkMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4B//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjHxsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+OjYyLiomIh4aFhIOCgYB/fn18e3p5eHd2dXRzcnFwb25tbGtqaWhnZmVkY2JhYF9eXVxbWllYV1ZVVFNSUVBPTk1MS0pJSEdGRURDQkFAPz49PDs6OTg3NjU0MzIxMC8uLSwrKikoJyYlJCMiISAfHh0cGxoZGBcWFRQTEhEQDw4NDAsKCQgHBgUEAwIBAAAh+QQFMgAXACwAAAAAEAAQAAAFU6AljmRpBVOqrqtFVXAsy9Q7VMMDzHHN/5UawGQC1CiWg4IoOiINAoGB6BxBENSjyIE4oFKMprYhIFgYkvTQpWWOqm6RcVBI2+/2AuXL6k8CcSYhACH5BAUyABcALAcACQAFAAIAAAUIYJSMBLGcSggAIfkEBTIAFwAsBwAJAAUAAgAABQhgMI0MI51ACAAh+QQFMgAXACwHAAkABQACAAAFCGCUjASxnEoIADs=");
}
/* menu end */
-11
View File
@@ -1,15 +1,4 @@
/* menu start */
.menu .menu_plugin_webssh {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAMBJREFUeNpiYKAQMM6cOVMASBuQozk9Pf0AC5AuAOJ6cgwAWt7IhMQvRKIfAPEEYgxhQWL3o9EFpBgwAeifQhKdD7YI5oWPUMEEmAQR4COyATBwAIgdgIacB2IFYkxhQouWB0BsCA3E86QGIsxvDSBXgGIDSxr5ALTgAk4XADWAQt4fiB2BChcAaQVoGoHheLwuAGqagBz/UNsciQ4DEgE/zAUfQM4DOt+eRANAYTMRZADIrxfIdMUFSnMzA0CAAQD0hjqnYxWD2gAAAABJRU5ErkJggg==");
}
.menu .current .menu_plugin_webssh:hover {
background-image: url("data:image/gif;base64,R0lGODlhEAAQAMQXAJ6ipUFITySRPIiMkDFRQuXm5jJKQy1kQCGeOzBXQSl3PiWLPVhfZSxrQCpxP9na2yeEPTREQ8LExmRqb5OXm/Hx8TU9RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ1IDc5LjE2MzQ5OSwgMjAxOC8wOC8xMy0xNjo0MDoyMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjMyQjYwMTU3OTA2QTExRUJCN0NFQUUwQjRDMzM4RDJDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjMyQjYwMTU4OTA2QTExRUJCN0NFQUUwQjRDMzM4RDJDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MzJCNjAxNTU5MDZBMTFFQkI3Q0VBRTBCNEMzMzhEMkMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MzJCNjAxNTY5MDZBMTFFQkI3Q0VBRTBCNEMzMzhEMkMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4B//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjHxsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+OjYyLiomIh4aFhIOCgYB/fn18e3p5eHd2dXRzcnFwb25tbGtqaWhnZmVkY2JhYF9eXVxbWllYV1ZVVFNSUVBPTk1MS0pJSEdGRURDQkFAPz49PDs6OTg3NjU0MzIxMC8uLSwrKikoJyYlJCMiISAfHh0cGxoZGBcWFRQTEhEQDw4NDAsKCQgHBgUEAwIBAAAh+QQFMgAXACwAAAAAEAAQAAAFU6AljmRpBVOqrqtFVXAsy9Q7VMMDzHHN/5UawGQC1CiWg4IoOiINAoGB6BxBENSjyIE4oFKMprYhIFgYkvTQpWWOqm6RcVBI2+/2AuXL6k8CcSYhACH5BAUyABcALAcACQAFAAIAAAUIYJSMBLGcSggAIfkEBTIAFwAsBwAJAAUAAgAABQhgMI0MI51ACAAh+QQFMgAXACwHAAkABQACAAAFCGCUjASxnEoIADs=");
}
/* menu end */
.xterm{
position: inherit;
}
+5 -4
View File
@@ -191,8 +191,10 @@ def pSqliteDb(dbname='web_logs', site_name='unset', name="logs"):
conn = mw.M(dbname).dbPos(db_dir, name)
conn.execute("PRAGMA synchronous = 0")
conn.execute("PRAGMA page_size = 4096")
conn.execute("PRAGMA cache_size = 8000")
conn.execute("PRAGMA page_size = 32768")
conn.execute("PRAGMA journal_mode = wal")
conn.execute("PRAGMA journal_size_limit = 1073741824")
return conn
@@ -263,6 +265,8 @@ def initDreplace():
loadLuaSiteFile()
loadDebugLogFile()
if not mw.isAppleSystem():
mw.execShell("chown -R www:www " + getServerDir())
return 'ok'
@@ -277,9 +281,6 @@ def start():
import tool_task
tool_task.createBgTask()
if not mw.isAppleSystem():
mw.execShell("chown -R www:www " + getServerDir())
# issues:326
luaRestart()
return 'ok'
+14 -2
View File
@@ -1,10 +1,22 @@
{
"sort": 7,
"hook":[
{
"tag":"site_cb",
"site_cb": {
"title":"网站统计",
"name":"webstats",
"add":{"func":"reload"},
"update":{"func":"reload"},
"delete":{"func":"reload"}
}
}
],
"sort": "7",
"ps": "网站统计报表",
"name": "webstats",
"title": "网站统计",
"shell": "install.sh",
"versions":["0.2.3"],
"versions":["0.2.5"],
"tip": "soft",
"install_pre_inspection":true,
"checks": "server/webstats",
+2 -1
View File
@@ -39,6 +39,7 @@ Install_App()
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/source/webstats
mkdir -p $serverPath/webstats
echo "${VERSION}" > $serverPath/webstats/version.pl
# 下载源码安装包
# curl -O $serverPath/source/webstats/lua-5.1.5.tar.gz https://www.lua.org/ftp/lua-5.1.5.tar.gz
@@ -110,7 +111,7 @@ Install_App()
cp -rf $serverPath/source/webstats/GeoLite2-City.mmdb $serverPath/webstats/GeoLite2-City.mmdb
fi
echo "${VERSION}" > $serverPath/webstats/version.pl
echo '安装完成' > $install_tmp
cd $rootPath && python3 ${rootPath}/plugins/webstats/index.py start
+53 -26
View File
@@ -36,20 +36,26 @@ function _M.new(self)
params = nil,
site_config = nil,
config = nil,
}
-- self.dbs = {}
return setmetatable(self, mt)
end
function _M.getInstance(self)
if rawget(self, "instance") == nil then
rawset(self, "instance", self.new())
-- function _M.getInstance(self)
-- if rawget(self, "instance") == nil then
-- rawset(self, "instance", self.new())
-- self.cron()
-- end
-- assert(self.instance ~= nil)
-- return self.instance
-- end
-- if 0 == ngx.worker.id() then
function _M.getInstance(self)
if self.instance == nil then
self.instance = self:new()
self:cron()
-- end
end
assert(self.instance ~= nil)
return self.instance
@@ -229,16 +235,46 @@ function _M.get_http_origin(self)
return json.encode(headers)
end
function _M.cronPre(self)
local time_key = self:get_store_key()
local time_key_next = self:get_store_key_with_time(ngx.time()+3600)
for site_k, site_v in ipairs(sites) do
local input_sn = site_v["name"]
local db = self:initDB(input_sn)
local wc_stat = {
'request_stat',
'client_stat',
'spider_stat'
}
for _,ws_v in pairs(wc_stat) do
self:_update_stat_pre(db, ws_v, time_key)
self:_update_stat_pre(db, ws_v, time_key_next)
end
if db and db:isopen() then
db:execute([[COMMIT]])
db:close()
end
end
end
-- 后台任务
function _M.cron(self)
local timer_every_get_data = function (premature)
local timer_every_get_data = function (premature)
local llen, _ = ngx.shared.mw_total:llen(total_key)
-- self:D("llen:"..tostring(llen))
-- self:D("PID:"..tostring(ngx.worker.id())..",llen:"..tostring(llen))
if llen == 0 then
return true
end
self:cronPre()
ngx.update_time()
local begin = ngx.now()
@@ -249,10 +285,10 @@ function _M.cron(self)
local url_stats = {}
local time_key = self:get_store_key()
local time_key_next = self:get_store_key_with_time(ngx.time()+3600)
for site_k, site_v in ipairs(sites) do
local input_sn = site_v["name"]
-- self:D("input_sn:"..input_sn)
-- 迁移合并时不执行
if self:is_migrating(input_sn) then
return true
@@ -276,18 +312,6 @@ function _M.cron(self)
tmp_stmt["web_logs"] = stmt
stmts[input_sn] = tmp_stmt
local wc_stat = {
'request_stat',
'client_stat',
'spider_stat'
}
for _,ws_v in pairs(wc_stat) do
self:_update_stat_pre(db, ws_v, time_key)
self:_update_stat_pre(db, ws_v, time_key_next)
end
db:exec([[BEGIN TRANSACTION]])
end
end
@@ -307,7 +331,10 @@ function _M.cron(self)
end
local info = json.decode(data)
-- self:D("info:"..json.encode(info))
local input_sn = info['server_name']
-- self:D("insert data input_sn:"..input_sn)
local db = dbs[input_sn]
local stat_fields_is = stat_fields[input_sn]
if not db then
@@ -458,10 +485,9 @@ function _M.cron(self)
self:unlock_working(cron_key)
ngx.update_time()
-- self:D("--【"..tostring(llen).."】, elapsed: " .. tostring(ngx.now() - begin))
-- self:D("PID:"..tostring(ngx.worker.id()).."--【"..tostring(llen).."】, elapsed: " .. tostring(ngx.now() - begin))
end
ngx.timer.every(1, timer_every_get_data)
ngx.timer.every(0.5, timer_every_get_data)
end
@@ -488,7 +514,7 @@ function _M.store_logs_line(self, db, stmt, input_sn, info)
local request_headers = logline["request_headers"]
local excluded = logline["excluded"]
-- self:D("json:"..json.encode(logline))
local time_key = logline["time_key"]
if not excluded then
@@ -1058,6 +1084,7 @@ end
function _M.get_client_ip(self)
local client_ip = "unknown"
local cdn = auto_config['cdn']
local request_header = ngx.req.get_headers()
if cdn == true then
for _,v in ipairs(auto_config['cdn_headers']) do
if request_header[v] ~= nil and request_header[v] ~= "" then
+6 -6
View File
@@ -8,7 +8,7 @@ log_by_lua_block {
package.path = cpath .. "?.lua;" .. package.path
end
local ver = '0.2.3'
local ver = '0.2.4'
local debug_mode = true
local __C = require "webstats_common"
@@ -44,7 +44,7 @@ log_by_lua_block {
local sites = require "webstats_sites"
-- string.gsub(C:get_sn(ngx.var.server_name),'_','.')
local server_name = ngx.var.server_name
local server_name = C:get_sn(ngx.var.server_name)
C:setConfData(config, sites)
@@ -210,7 +210,7 @@ log_by_lua_block {
-- local request_time = ngx.var.request_time
local request_time = C:get_request_time()
local client_port = ngx.var.remote_port
local real_server_name = server_name
local real_server_name = ngx.var.server_name
local uri = ngx.var.uri
local status_code = ngx.status
local protocol = ngx.var.server_protocol
@@ -439,7 +439,7 @@ log_by_lua_block {
}
local push_data = json.encode(data)
-- C:D(json.encode(push_data))
local key = C:getTotalKey()
ngx.shared.mw_total:rpush(key, push_data)
end
@@ -630,7 +630,7 @@ log_by_lua_block {
end
local function run_app()
-- D("------------ debug start ------------")
-- C:D("------------ debug start ------------")
init_var()
load_global_exclude_ip()
@@ -641,7 +641,7 @@ log_by_lua_block {
-- cache_logs_old(server_name)
-- store_logs(server_name)
-- D("------------ debug end -------------")
-- C:D("------------ debug end -------------")
end
+12 -8
View File
@@ -179,7 +179,6 @@ def requestCheck():
def isLogined():
# print('isLogined', session)
if 'login' in session and 'username' in session and session['login'] == True:
userInfo = mw.M('users').where(
"id=?", (1,)).field('id,username,password').find()
@@ -386,7 +385,10 @@ def get_admin_safe():
def admin_safe_path(path, req, data, pageFile):
if path != req and not isLogined():
return render_template('path.html')
if data['status_code'] == '0':
return render_template('path.html')
else:
return Response(status=int(data['status_code']))
if not isLogined():
return render_template('login.html', data=data)
@@ -442,7 +444,6 @@ def login_temp_user(token):
@app.route('/api/<reqClass>/<reqAction>', methods=['POST', 'GET'])
def api(reqClass=None, reqAction=None, reqData=None):
comReturn = common.local()
if comReturn:
return comReturn
@@ -455,15 +456,18 @@ def api(reqClass=None, reqAction=None, reqData=None):
request_time = request.form.get('request_time', '')
request_token = request.form.get('request_token', '')
request_ip = request.remote_addr
request_ip = request_ip.replace('::ffff:', '')
token_md5 = mw.md5(str(request_time) + mw.md5(data['token_crypt']))
# print(request_time, request_token)
if not mw.inArray(data['limit_addr'], request_ip):
return mw.returnJson(False, 'IP校验失败,您的访问IP为[' + request_ip + ']')
local_token = mw.deCrypt(data['token'], data['token_crypt'])
token_md5 = mw.md5(str(request_time) + mw.md5(local_token))
if not (token_md5 == request_token):
return mw.returnJson(False, '密钥错误')
if not mw.inArray(data['limit_addr'], request_ip):
return mw.returnJson(False, '非法请求')
if reqClass == None:
return mw.returnJson(False, '请指定请求方法类')
@@ -474,7 +478,7 @@ def api(reqClass=None, reqAction=None, reqData=None):
'plugins_api', 'system_api', 'site_api', 'task_api')
className = reqClass + '_api'
if not className in classFile:
return "external api request error"
return mw.returnJson(False, 'external api request error')
eval_str = "__import__('" + className + "')." + className + '()'
newInstance = eval(eval_str)
+55
View File
@@ -550,6 +550,61 @@ function setTempAccessReq(page){
},'json');
}
function setStatusCode(o){
var code = $(o).data('code');
layer.open({
type: 1,
area: ['420px', '220px'],
title: "设置未认证时的响应状态",
closeBtn: 1,
shift: 5,
btn:['提交','关闭'],
shadeClose: false,
content: '<div class="bt-form bt-form pd20">\
<div class="line">\
<span class="tname">相应状态</span>\
<div class="info-r">\
<select class="bt-input-text mr5" name="status_code" style="width: 250px;"></select>\
</div>\
</div>\
<ul class="help-info-text c7"><li style="color: red;">用于未登录且未正确输入安全入口时的响应,用于隐藏面板特征</li></ul>\
</div>',
success:function(){
var msg_list = [
{'code':'0','msg':'默认-安全入口错误提示'},
{'code':'403','msg':'403-拒绝访问'},
{'code':'404','msg':'404-页面不存在'},
{'code':'416','msg':'416-无效的请求'},
{'code':'408','msg':'408-客户端超时'},
{'code':'400','msg':'400-客户端请求错误'},
{'code':'401','msg':'401-未授权访问'},
];
var tbody = '';
for(i in msg_list){
if (msg_list[i]['code'] == code){
tbody += '<option value="'+msg_list[i]['code']+'" selected>'+msg_list[i]['msg']+'</option>';
} else{
tbody += '<option value="'+msg_list[i]['code']+'">'+msg_list[i]['msg']+'</option>';
}
}
$('select[name="status_code"]').append(tbody);
},
yes:function(index){
var loadT = layer.msg("正在设置未认证时的响应状态", { icon: 16, time: 0, shade: [0.3, '#000'] });
var status_code = $('select[name="status_code"]').val();
$.post('/config/set_status_code', { status_code: status_code }, function (rdata) {
showMsg(rdata.msg, function(){
layer.close(index);
layer.close(loadT);
location.reload();
},{ icon: rdata.status ? 1 : 2 }, 2000);
},'json');
}
});
}
function setTempAccess(){
layer.open({
area: ['700px', '250px'],
+8 -1
View File
@@ -257,7 +257,7 @@ function planAdd(){
$("#set-Config input[name='sType']").val(sType);
$("#set-Config textarea[name='sBody']").val(decodeURIComponent(sBody));
if(sType == 'site' || sType == 'database'){
if(sType == 'site' || sType == 'database' || sType == 'path'){
var backupTo = $(".planBackupTo").find("b").attr("val");
$("#backupTo").val(backupTo);
}
@@ -293,10 +293,17 @@ function planAdd(){
var where1 = $("#ptime input[name='where1']").val();
$("#set-Config input[name='where1']").val(where1);
}
if (type == 'month'){
var where1 = $("#ptime input[name='where1']").val();
$("#set-Config input[name='where1']").val(where1);
}
$("#set-Config input[name='sName']").val(sName);
layer.msg('正在添加,请稍候...!',{icon:16,time:0,shade: [0.3, '#000']});
var data = $("#set-Config").serialize() + '&sBody='+sBody + '&urladdress=' + urladdress;
// console.log(data);
$.post('/crontab/add',data,function(rdata){
if(!rdata.status) {
layer.msg(rdata.msg,{icon:2, time:2000});
+1 -1
View File
@@ -1110,7 +1110,7 @@ function reName(type, fileName) {
</div>',
success:function(){
$("#newFileName").focus().keyup(function(e){
if(e.keyCode == 13) $("#ReNameBtn").click();
if(e.keyCode == 13) $(".layui-layer-btn0").click();
});
},
yes:function(){
+32 -22
View File
@@ -648,7 +648,11 @@ function onlineEditFile(k, f) {
"Ctrl-S": function() {
$("#textBody").text(t.getValue());
onlineEditFile(2, f)
}
},
"Cmd-S":function() {
$("#textBody").text(t.getValue());
onlineEditFile(2, f)
},
},
mode: d,
lineNumbers: true,
@@ -2188,39 +2192,45 @@ function pluginRollingLogs(_name, version, func, _args, line){
var reqTimer = null;
function requestLogs(fileName){
$.post('/files/get_last_body', 'path=' + fileName+'&line='+file_line, function(rdata) {
if (!rdata.status){
return;
}
if(rdata.data == '') {
rdata.data = '当前没有日志!';
}
var ebody = '<textarea readonly="readonly" style="margin: 0px;width: 100%;height: 360px;background-color: #333;color:#fff; padding:0 5px" id="roll_info_log">'+rdata.data+'</textarea>';
$("#plugins_rolling_logs").html(ebody);
var ob = document.getElementById('roll_info_log');
ob.scrollTop = ob.scrollHeight;
},'json');
}
layer.open({
type: 1,
title: _name + '日志',
area: '640px',
end: function(){
// console.log('end!!!');
if (reqTimer){
clearInterval(reqTimer);
}
},
content:'<div class="change-default pd20" id="plugins_rolling_logs">\
<textarea readonly="readonly" style="margin: 0px;width: 100%;height: 360px;background-color: #333;color:#fff; padding:0 5px" id="roll_info_log"></textarea>\
</div>'
</div>',
success:function(){
$.post('/plugins/run', {name:_name, func:func_name, version:version, args:_args},function (data) {
var fileName = data.data;
requestLogs(fileName);
reqTimer = setInterval(function(){
requestLogs(fileName);
},1000);
},'json');
}
});
$.post('/plugins/run', {name:_name, func:func_name, version:version,args:_args},function (data) {
var fileName = data.data;
reqTimer = setInterval(function(){
$.post('/files/get_last_body', 'path=' + fileName+'&line='+file_line, function(rdata) {
if (!rdata.status){
return;
}
if(rdata.data == '') {
rdata.data = '当前没有日志!';
}
var ebody = '<textarea readonly="" style="margin: 0px;width: 100%;height: 360px;background-color: #333;color:#fff; padding:0 5px" id="roll_info_log">'+rdata.data+'</textarea>';
$("#plugins_rolling_logs").html(ebody);
var ob = document.getElementById('roll_info_log');
ob.scrollTop = ob.scrollHeight;
},'json');
},1000);
},'json');
}
+1 -1
View File
@@ -200,7 +200,7 @@ function webAddPage(type) {
}
domainlist = domainlist.substring(0,domainlist.length-1);//子域名json
domain ='{"domain":"'+domain[0]+'","domainlist":['+domainlist+'],"count":'+domain.length+'}';//拼接joson
domain ='{"domain":"'+domain[0]+'","domainlist":['+domainlist+'],"count":'+domain.length+'}';//拼接json
var loadT = layer.msg(lan.public.the_get,{icon:16,time:0,shade: [0.3, "#000"]})
var data = $("#addweb").serialize()+"&port="+webport+"&webinfo="+domain;
+129 -132
View File
@@ -1,155 +1,152 @@
{% extends "layout.html" %}
{% block content %}
<div class="main-content">
<div class="container-fluid" style="padding-bottom:54px">
<div class="pos-box bgw mtb15">
<div class="position f14 c9 pull-left">
<a class="plr10 c4" href="/">首页</a>/<span class="plr10 c4">面板设置</span>
<div class="container-fluid" style="padding-bottom:54px">
<div class="pos-box bgw mtb15">
<div class="position f14 c9 pull-left"><a class="plr10 c4" href="/">首页</a>/<span class="plr10 c4">面板设置</span></div>
</div>
<div class="clearfix bgw mtb15 pd15">
<div class="safe-port pull-left">
<div class="ss-text pull-left mr50">
<em>关闭面板</em>
<div class="ssh-item">
<input class="btswitch btswitch-ios" id="closePl" type="checkbox">
<label class="btswitch-btn" for="closePl" onclick="closePanel()"></label>
</div>
</div>
<div class="ss-text pull-left mr50">
<em>开发模式</em>
<div class="ssh-item">
<input class="btswitch btswitch-ios" id="debugMode" type="checkbox" {{data['debug']}}>
<label class="btswitch-btn" for="debugMode" onclick="debugMode()"></label>
</div>
</div>
<div class="ss-text pull-left mr50">
<em title="开启后允许使用ipv6访问面板">监听IPv6</em>
<div class='ssh-item'>
<input class='btswitch btswitch-ios' id='panelIPv6' type='checkbox' {{data['ipv6']}}>
<label class='btswitch-btn' for='panelIPv6' onclick="setIPv6()"></label>
</div>
</div>
</div>
<div class="clearfix bgw mtb15 pd15">
<div class="safe-port pull-left">
<div class="ss-text pull-left mr50">
<em>关闭面板</em>
<div class="ssh-item">
<input class="btswitch btswitch-ios" id="closePl" type="checkbox">
<label class="btswitch-btn" for="closePl" onclick="closePanel()"></label>
</div>
</div>
<div class="ss-text pull-left mr50">
<em>开发模式</em>
<div class="ssh-item">
<input class="btswitch btswitch-ios" id="debugMode" type="checkbox" {{data['debug']}}>
<label class="btswitch-btn" for="debugMode" onclick="debugMode()"></label>
</div>
</div>
<div class="ss-text pull-left mr50">
<em title="开启后允许使用ipv6访问面板">监听IPv6</em>
<div class='ssh-item'>
<input class='btswitch btswitch-ios' id='panelIPv6' type='checkbox' {{data['ipv6']}}>
<label class='btswitch-btn' for='panelIPv6' onclick="setIPv6()"></label>
</div>
</div>
</div>
</div>
<div class="setbox bgw mtb15">
<div class="title c6 plr15"><h3 class="f16">设置</h3></div>
<div class="info-title-tips" style="margin: 20px 30px 0px;">
<p><span class="glyphicon glyphicon-alert" style="color: #f39c12; margin-right: 10px;"></span>为了提高安全,修改面板密码!</p>
</div>
<div class="setbox bgw mtb15">
<div class="title c6 plr15">
<h3 class="f16">设置</h3>
</div>
<div class="info-title-tips" style="margin: 20px 30px 0px;">
<p><span class="glyphicon glyphicon-alert" style="color: #f39c12; margin-right: 10px;"></span>为了提高安全,修改面板密码!</p>
</div>
<div class="setting-con pd15">
<form id="set_config">
<p class="mtb15">
<span class="set-tit text-right">别名</span>
<input id="webname" name="webname" class="inputtxt bt-input-text" type="text" value="{{data['title']}}">
<button type="button" class="btn btn-success btn-sm ml5 btn_webname" disabled>保存</button>
<span class="set-info c7">面板名称</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="服务器IP">服务器IP</span>
<input name="host_ip" class="inputtxt bt-input-text" type="text" value="{{data['ip']}}">
<button type="button" class="btn btn-success btn-sm ml5 btn_host_ip" disabled>保存</button>
<span class="set-info c7">默认为外网IP,若您在本地虚拟机测试,请填写虚拟机内网IP!</span>
</p>
<p class="mtb15">
<span class="set-tit text-right">面板端口</span>
<input id="banport" name="port" class="inputtxt bt-input-text" type="numner" value="{{data['port']}}" maxlength="5">
<button type="button" class="btn btn-success btn-sm ml5 btn_port" disabled>保存</button>
<span class="set-info c7">建议端口范围7200 - 65535</span>
</p>
<p class="mtb15">
<span class="set-tit text-right">安全入口</span>
<input id="admin_path" name="admin_path" class="inputtxt bt-input-text disable" type="text" value="{{data['admin_path']}}">
<button type="button" class="btn btn-success btn-sm ml5" onclick="modifyAuthPath()">设置</button>
<span class="set-info c7">面板管理入口,设置后只能通过指定安全入口登录面板,如: /abc</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="默认建站目录">默认建站目录</span>
<input name="sites_path" class="inputtxt bt-input-text" type="text" value="{{data['site_path']}}">
<button type="button" class="btn btn-success btn-sm ml5 btn_sites_path" disabled>保存</button>
<span class="set-info c7">新创建的站点,默认将保存到该目录的下级目录!</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="默认建站目录">默认备份目录</span>
<input name="backup_path" class="inputtxt bt-input-text" type="text" value="{{data['backup_path']}}">
<button type="button" class="btn btn-success btn-sm ml5 btn_backup_path" disabled>保存</button>
<span class="set-info c7">网站和数据库的备份目录!</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="服务器时间">服务器时间</span>
<input id="systemdate" name="systemdate" class="inputtxt bt-input-text disable" type="text" value="{{data['systemdate']}}">
<button type="button" class="btn btn-success btn-sm ml5" onclick="syncDate()">同步</button>
<span class="set-info c7">同步当前服务器时间</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="面板用户">面板用户</span>
<input name="username_" class="inputtxt bt-input-text disable" type="text" value="{{data['username']}}" disabled>
<button type="button" class="btn btn-success btn-sm ml5" onclick="setUserName()">设置</button>
<span class="set-info c7">设置面板账号</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="面板密码">面板密码</span>
<input name="password_" class="inputtxt bt-input-text disable" type="text" value="******" disabled>
<button type="button" class="btn btn-success btn-sm ml5" onclick="setPassword()">设置</button>
<span class="set-info c7">设置面板密码</span>
</p>
</form>
</div>
<div class="title c6 plr15">
<h3 class="f16">安全</h3>
</div>
<div class="setting-con pd15">
<div class="setting-con pd15">
<form id="set_config">
<p class="mtb15">
<span class="set-tit text-right" title="绑定域名" style="float: left;">绑定域名</span>
<input name="bind_domain" class="inputtxt bt-input-text" type="text" value="{{data['bind_domain']}}">
<button type="button" class="btn btn-success btn-sm ml5 btn_bind_domain" disabled>保存</button>
<span class="set-info c7">为面板绑定一个访问域名,<b style="color: red;">注意:一旦绑定域名,只能通过域名访问面板</b></span>
<span class="set-tit text-right">别名</span>
<input id="webname" name="webname" class="inputtxt bt-input-text" type="text" value="{{data['title']}}">
<button type="button" class="btn btn-success btn-sm ml5 btn_webname" disabled>保存</button>
<span class="set-info c7">面板名称</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="面板SSL" style="float: left;">面板SSL</span>
<input id="cfg_ssl" name="bind_ssl" class="btswitch btswitch-ios" type="checkbox" {{data['ssl']}}>
<label class="btswitch-btn ml5" for="cfg_ssl" style="float: left;margin-top:4px;"></label>
<button ype="button" class="btn btn-default btn-xs panel_api_btn" style="vertical-align: middle; margin-left: 10px" onclick="getPanelSSL();">面板SSL配置</button>
<span class="set-info c7">为面板设置https协议访问,提升面板访问<b style="color: red;">安全性</b></span>
<span class="set-tit text-right" title="服务器IP">服务器IP</span>
<input name="host_ip" class="inputtxt bt-input-text" type="text" value="{{data['ip']}}">
<button type="button" class="btn btn-success btn-sm ml5 btn_host_ip" disabled>保存</button>
<span class="set-info c7">默认为外网IP,若您在本地虚拟机测试,请填写虚拟机内网IP!</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="BasicAuth认证" style="float: left;">BasicAuth认证</span>
<input class="btswitch btswitch-ios" id="cfg_basic_auth" type="checkbox" {{data['basic_auth']}}/>
<label class="btswitch-btn ml5" for="cfg_basic_auth" style="float: left;margin-top:4px;" onclick="setBasicAuth()"></label>
<span class="set-info c7">为面板增加一道基于BasicAuth的认证服务,有效防止面板被扫描</span>
<span class="set-tit text-right">面板端口</span>
<input id="banport" name="port" class="inputtxt bt-input-text" type="numner" value="{{data['port']}}" maxlength="5">
<button type="button" class="btn btn-success btn-sm ml5 btn_port" disabled>保存</button>
<span class="set-info c7">建议端口范围7200 - 65535</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="API接口" style="float: left;">API接口</span>
<input class="btswitch btswitch-ios" id="cfg_panel_api" type="checkbox" {{data['api_token']}}/>
<label class="btswitch-btn ml5" for="cfg_panel_api" style="float: left;margin-top:4px;" onclick="setPanelApi()"></label>
<button ype="button" class="btn btn-default btn-xs panel_api_btn" style="vertical-align: middle; margin-left: 10px" onclick="showPanelApi();">API接口配置</button>
<span class="set-info c7">提供面板API接口访问的支持</span>
<span class="set-tit text-right">安全入口</span>
<input id="admin_path" name="admin_path" class="inputtxt bt-input-text disable" type="text" value="{{data['admin_path']}}">
<button type="button" class="btn btn-success btn-sm ml5" onclick="modifyAuthPath()">设置</button>
<span class="set-info c7">面板管理入口,设置后只能通过指定安全入口登录面板,如: /abc</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="临时访问授权">临时访问授权</span>
<button type="button" class="btn btn-success btn-sm ml5" onclick="setTempAccess()">临时访问授权管理</button>
<span class="set-info c7">为非管理员临时提供面板访问权限</span>
<span class="set-tit text-right" title="默认建站目录">默认建站目录</span>
<input name="sites_path" class="inputtxt bt-input-text" type="text" value="{{data['site_path']}}">
<button type="button" class="btn btn-success btn-sm ml5 btn_sites_path" disabled>保存</button>
<span class="set-info c7">新创建的站点,默认将保存到该目录的下级目录!</span>
</p>
</div>
<p class="mtb15">
<span class="set-tit text-right" title="默认建站目录">默认备份目录</span>
<input name="backup_path" class="inputtxt bt-input-text" type="text" value="{{data['backup_path']}}">
<button type="button" class="btn btn-success btn-sm ml5 btn_backup_path" disabled>保存</button>
<span class="set-info c7">网站和数据库的备份目录!</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="服务器时间">服务器时间</span>
<input id="systemdate" name="systemdate" class="inputtxt bt-input-text disable" type="text" value="{{data['systemdate']}}">
<button type="button" class="btn btn-success btn-sm ml5" onclick="syncDate()">同步</button>
<span class="set-info c7">同步当前服务器时间</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="面板用户">面板用户</span>
<input name="username_" class="inputtxt bt-input-text disable" type="text" value="{{data['username']}}" disabled>
<button type="button" class="btn btn-success btn-sm ml5" onclick="setUserName()">设置</button>
<span class="set-info c7">设置面板账号</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="面板密码">面板密码</span>
<input name="password_" class="inputtxt bt-input-text disable" type="text" value="******" disabled>
<button type="button" class="btn btn-success btn-sm ml5" onclick="setPassword()">设置</button>
<span class="set-info c7">设置面板密码</span>
</p>
</form>
</div>
<div class="title c6 plr15"><h3 class="f16">安全</h3></div>
<div class="setting-con pd15">
<p class="mtb15">
<span class="set-tit text-right" title="绑定域名" style="float: left;">绑定域名</span>
<input name="bind_domain" class="inputtxt bt-input-text" type="text" value="{{data['bind_domain']}}">
<button type="button" class="btn btn-success btn-sm ml5 btn_bind_domain" disabled>保存</button>
<span class="set-info c7">为面板绑定一个访问域名,<b style="color: red;">注意:一旦绑定域名,只能通过域名访问面板</b></span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="面板SSL" style="float: left;">面板SSL</span>
<input id="cfg_ssl" name="bind_ssl" class="btswitch btswitch-ios" type="checkbox" {{data['ssl']}}>
<label class="btswitch-btn ml5" for="cfg_ssl" style="float: left;margin-top:4px;"></label>
<button ype="button" class="btn btn-default btn-xs panel_api_btn" style="vertical-align: middle; margin-left: 10px" onclick="getPanelSSL();">面板SSL配置</button>
<span class="set-info c7">为面板设置https协议访问,提升面板访问<b style="color: red;">安全性</b></span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="BasicAuth认证" style="float: left;">BasicAuth认证</span>
<input class="btswitch btswitch-ios" id="cfg_basic_auth" type="checkbox" {{data['basic_auth']}}/>
<label class="btswitch-btn ml5" for="cfg_basic_auth" style="float: left;margin-top:4px;" onclick="setBasicAuth()"></label>
<span class="set-info c7">为面板增加一道基于BasicAuth的认证服务,有效防止面板被扫描</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="API接口" style="float: left;">API接口</span>
<input class="btswitch btswitch-ios" id="cfg_panel_api" type="checkbox" {{data['api_token']}}/>
<label class="btswitch-btn ml5" for="cfg_panel_api" style="float: left;margin-top:4px;" onclick="setPanelApi()"></label>
<button ype="button" class="btn btn-default btn-xs panel_api_btn" style="vertical-align: middle; margin-left: 10px" onclick="showPanelApi();">API接口配置</button>
<span class="set-info c7">提供面板API接口访问的支持</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="未认证响应状态">未认证响应状态</span>
<input name="status_code" class="inputtxt bt-input-text disable" type="text" value="{{data['status_code_msg']}}" disabled>
<button type="button" class="btn btn-success btn-sm ml5" data-code="{{data['status_code']}}" onclick="setStatusCode(this)">设置</button>
<span class="set-info c7">用于在未登录且未正确输入安全入口时的响应,可用于隐藏面板特征</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="临时访问授权">临时访问授权</span>
<button type="button" class="btn btn-success btn-sm ml5" onclick="setTempAccess()">临时访问授权管理</button>
<span class="set-info c7">为非管理员临时提供面板访问权限</span>
</p>
</div>
</div>
</div>
+42 -29
View File
@@ -2,35 +2,42 @@
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit">
<title>{{data['title']}}</title>
<link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon" />
<link href="/static/bootstrap-3.3.5/css/bootstrap.min.css?v={{config.version}}" rel="stylesheet">
<link href="/static/css/site.css?v={{config.version}}" rel="stylesheet">
<link href="/static/codemirror/lib/codemirror.css?v={{config.version}}" rel="stylesheet">
<script src="/static/language/Simplified_Chinese/lan.js?v={{config.version}}"></script>
<!--[if lte IE 9]>
<script src="/static/js/requestAnimationFrame.js"></script>
<![endif]-->
<!-- 统计一下用户量,让我的开发更有激情 -->
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-FC74BB2RGD"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-FC74BB2RGD');
</script>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit">
<title>{{data['title']}}</title>
<link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon" />
<link href="/static/bootstrap-3.3.5/css/bootstrap.min.css?v={{config.version}}" rel="stylesheet">
<link href="/static/css/site.css?v={{config.version}}" rel="stylesheet">
<link href="/static/codemirror/lib/codemirror.css?v={{config.version}}" rel="stylesheet">
<script src="/static/language/Simplified_Chinese/lan.js?v={{config.version}}"></script>
<!--[if lte IE 9]>
<script src="/static/js/requestAnimationFrame.js"></script>
<![endif]-->
<!-- 统计一下用户量,让我的开发更有激情 -->
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-FC74BB2RGD"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-FC74BB2RGD');
</script>
{% for menu in data['hook_menu'] %}
{% if menu['js_path'] %}
<!-- 加载插件css -->
<link href="/plugins/file?name={{menu['name']}}&v={{config.version}}&f={{menu['css_path']}}" rel="stylesheet" />
{% endif %}
{% endfor %}
{% for menu in data['hook_menu'] %}
{% if menu['css_path'] and data['hook_tag'] == menu['name'] %}
<!-- 加载插件css -->
<link href="/plugins/file?name={{menu['name']}}&v={{config.version}}&f={{menu['css_path']}}" rel="stylesheet" />
{% endif %}
{% endfor %}
<!-- 全局静态HOOK -->
{% for menu in data['hook_global_static'] %}
{% if menu['css_path'] %}
<link href="/plugins/file?name={{menu['name']}}&v={{config.version}}&f={{menu['css_path']}}" rel="stylesheet" />
{% endif %}
{% endfor %}
</head>
<body>
@@ -85,9 +92,9 @@
<div class="footer bgw">mdserver-web &copy;2018-∞ Linux面板 (<a class="btlink" target="_blank" href="//github.com/midoks/mdserver-web">源码</a>) <span style="margin-left:5px;">/</span>
<a class="btlink" style="margin-left:5px;" href="//github.com/midoks/mdserver-web/wiki" target="_blank">WIKI</a><span style="margin-left:5px;">/</span>
<a class='btlink panel_ad_list_mode' style="margin-left:5px;">AD</a>
</div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
@@ -158,8 +165,14 @@ if (thisPath.indexOf('?')>-1){
<script src="/static/laydate/laydate.js?v={{config.version}}"></script>
{% for menu in data['hook_menu'] %}
{% if menu['js_path'] and data['hook_tag'] == menu['name'] %}
<script src="/plugins/file?name={{menu['name']}}&f={{menu['js_path']}}&v={{config.version}}"></script>
{% endif %}
{% endfor %}
<!-- 全局静态HOOK -->
{% for menu in data['hook_global_static'] %}
{% if menu['js_path'] %}
<!-- 加载插件js -->
<script src="/plugins/file?name={{menu['name']}}&f={{menu['js_path']}}&v={{config.version}}"></script>
{% endif %}
{% endfor %}
+2 -2
View File
@@ -10,7 +10,7 @@
</div>
<div class="search pull-right">
<form target="hid" onsubmit='getSList()'>
<input type="text" id="SearchValue" class="ser-text pull-left" placeholder="search" />
<input type="text" id="SearchValue" class="ser-text pull-left" placeholder="搜索" />
<button type="button" class="ser-sub pull-left" onclick='getSList()'></button>
</form>
</div>
@@ -27,7 +27,7 @@
<table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">
<thead>
<tr>
<th width="165">软件名称</th>
<th width="185">软件名称</th>
<th>说明</th>
<th width="40">位置</th>
<th width="40">状态</th>
+29 -15
View File
@@ -5,6 +5,7 @@
import sys
import os
import re
if sys.platform != 'darwin':
os.chdir('/www/server/mdserver-web')
@@ -50,7 +51,6 @@ class backupTools:
mw.execShell(cmd)
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
print(filename)
if not os.path.exists(filename):
log = "网站[" + name + "]备份失败!"
@@ -83,6 +83,27 @@ class backupTools:
if num < 1:
break
def getConf(self, mtype='mysql'):
path = mw.getServerDir() + '/' + mtype + '/etc/my.cnf'
return path
# 数据库密码处理
def mypass(self, act, root):
conf_file = self.getConf('mysql')
mw.execShell("sed -i '/user=root/d' {}".format(conf_file))
mw.execShell("sed -i '/password=/d' {}".format(conf_file))
if act:
mycnf = mw.readFile(conf_file)
src_dump = "[mysqldump]\n"
sub_dump = src_dump + "user=root\npassword=\"{}\"\n".format(root)
if not mycnf:
return False
mycnf = mycnf.replace(src_dump, sub_dump)
if len(mycnf) > 100:
mw.writeFile(conf_file, mycnf)
return True
return True
def backupDatabase(self, name, count):
db_path = mw.getServerDir() + '/mysql'
db_name = 'mysql'
@@ -104,17 +125,11 @@ class backupTools:
filename = backup_path + "/db_" + name + "_" + \
time.strftime('%Y%m%d_%H%M%S', time.localtime()) + ".sql.gz"
import re
mysql_root = mw.M('config').dbPos(db_path, db_name).where(
"id=?", (1,)).getField('mysql_root')
mycnf = mw.readFile(db_path + '/etc/my.cnf')
rep = "\[mysqldump\]\nuser=root"
sea = "[mysqldump]\n"
subStr = sea + "user=root\npassword=" + mysql_root + "\n"
mycnf = mycnf.replace(sea, subStr)
if len(mycnf) > 100:
mw.writeFile(db_path + '/etc/my.cnf', mycnf)
my_cnf = self.getConf('mysql')
self.mypass(True, mysql_root)
# mw.execShell(db_path + "/bin/mysqldump --opt --default-character-set=utf8 " +
# name + " | gzip > " + filename)
@@ -125,8 +140,10 @@ class backupTools:
# mw.execShell(db_path + "/bin/mysqldump --single-transaction --quick --default-character-set=utf8 " +
# name + " | gzip > " + filename)
mw.execShell(db_path + "/bin/mysqldump --force --opt --default-character-set=utf8 " +
name + " | gzip > " + filename)
cmd = db_path + "/bin/mysqldump --defaults-file=" + my_cnf + " --force --opt --default-character-set=utf8 " + \
name + " | gzip > " + filename
# print(cmd)
mw.execShell(cmd)
if not os.path.exists(filename):
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
@@ -136,10 +153,7 @@ class backupTools:
"----------------------------------------------------------------------------")
return
mycnf = mw.readFile(db_path + '/etc/my.cnf')
mycnf = mycnf.replace(subStr, sea)
if len(mycnf) > 100:
mw.writeFile(db_path + '/etc/my.cnf', mycnf)
self.mypass(False, mysql_root)
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
outTime = time.time() - startTime
+36 -17
View File
@@ -14,7 +14,7 @@
PATH=/usr/local/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
# export LANG=en_US.UTF-8
export LANG=en_US.UTF-8
mw_path={$SERVER_PATH}
PATH=$PATH:$mw_path/bin
@@ -38,7 +38,7 @@ mw_start_panel()
sleep 0.5
isStart=$(lsof -n -P -i:$port|grep LISTEN|grep -v grep|awk '{print $2}'|xargs)
let n+=1
if [ $n -gt 15 ];then
if [ $n -gt 20 ];then
break;
fi
done
@@ -98,7 +98,7 @@ mw_stop_task()
arr=($pids)
for p in ${arr[@]}
do
kill -9 $p
kill -9 $p > /dev/null 2>&1
done
echo -e "\033[32mdone\033[0m"
}
@@ -109,7 +109,7 @@ mw_stop_panel()
arr=`ps aux|grep 'gunicorn -c setting.py app:app'|grep -v grep|awk '{print $2}'`
for p in ${arr[@]}
do
kill -9 $p &>/dev/null
kill -9 $p > /dev/null 2>&1
done
pidfile=${mw_path}/logs/mw.pid
@@ -196,32 +196,44 @@ error_logs()
mw_update()
{
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ];then
curl -fsSL https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/update.sh | bash
LOCAL_ADDR=common
ping -c 1 github.com > /dev/null 2>&1
if [ "$?" != "0" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "common" ];then
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/update.sh | bash
else
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/update.sh | bash
curl --insecure -fsSL https://gitee.com/midoks/mdserver-web/raw/master/scripts/install.sh | bash
fi
}
mw_update_dev()
{
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ];then
curl -fsSL https://gitee.com/midoks/mdserver-web/raw/dev/scripts/update_dev.sh | bash
LOCAL_ADDR=common
ping -c 1 github.com > /dev/null 2>&1
if [ "$?" != "0" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "common" ];then
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/update_dev.sh | bash
else
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/update_dev.sh | bash
curl --insecure -fsSL https://gitee.com/midoks/mdserver-web/raw/dev/scripts/update_dev.sh | bash
fi
cd /www/server/mdserver-web
}
mw_mirror()
{
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ];then
bash <(curl -sSL https://gitee.com/SuperManito/LinuxMirrors/raw/main/ChangeMirrors.sh)
LOCAL_ADDR=common
ping -c 1 github.com > /dev/null 2>&1
if [ "$?" != "0" ];then
LOCAL_ADDR=cn
fi
if [ "$LOCAL_ADDR" == "common" ];then
bash <(curl --insecure -sSL https://raw.githubusercontent.com/midoks/change-linux-mirrors/main/change-mirrors.sh)
else
bash <(curl -sSL https://raw.githubusercontent.com/midoks/change-linux-mirrors/main/change-mirrors.sh)
bash <(curl --insecure -sSL https://gitee.com/SuperManito/LinuxMirrors/raw/main/ChangeMirrors.sh)
fi
cd /www/server/mdserver-web
}
@@ -313,11 +325,18 @@ case "$1" in
auth_path=$(cat $mw_path/data/admin_path.pl)
fi
if [ "$address" = "" ];then
if [ "$address" == "" ];then
v4=$(python3 $mw_path/tools.py getServerIp 4)
v6=$(python3 $mw_path/tools.py getServerIp 6)
if [ "$v4" != "" ] && [ "$v6" != "" ]; then
if [ ! -f $mw_path/data/ipv6.pl ];then
echo 'True' > $mw_path/data/ipv6.pl
mw_stop
mw_start
fi
address="MW-Panel-Url-Ipv4: http://$v4:$port$auth_path \nMW-Panel-Url-Ipv6: http://[$v6]:$port$auth_path"
elif [ "$v4" != "" ]; then
address="MW-Panel-Url: http://$v4:$port$auth_path"
+27 -9
View File
@@ -56,6 +56,16 @@ else
fi
# cn=$(curl --insecure -fsSL -m 10 https://ipinfo.io/json | grep "\"country\": \"CN\"")
HTTP_PREFIX="https://"
LOCAL_ADDR=common
ping -c 1 github.com > /dev/null 2>&1
if [ "$?" != "0" ];then
LOCAL_ADDR=cn
HTTP_PREFIX="https://ghproxy.com/"
fi
if [ $OSNAME != "macos" ];then
if id www &> /dev/null ;then
echo ""
@@ -71,11 +81,8 @@ if [ $OSNAME != "macos" ];then
mkdir -p /www/backup/site
# https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/install.sh
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -d /www/server/mdserver-web ];then
if [ ! -z "$cn" ];then
if [ "$LOCAL_ADDR" != "common" ];then
curl -sSLo /tmp/master.zip https://gitee.com/midoks/mdserver-web/repository/archive/master.zip
else
curl -sSLo /tmp/master.zip https://codeload.github.com/midoks/mdserver-web/zip/master
@@ -89,8 +96,8 @@ if [ $OSNAME != "macos" ];then
# install acme.sh
if [ ! -d /root/.acme.sh ];then
if [ ! -z "$cn" ];then
curl -sSL -o /tmp/acme.tar.gz https://ghproxy.com/github.com/acmesh-official/acme.sh/archive/master.tar.gz
if [ "$LOCAL_ADDR" != "common" ];then
curl -sSLo /tmp/acme.tar.gz https://gitee.com/neilpang/acme.sh/repository/archive/master.tar.gz
tar xvzf /tmp/acme.tar.gz -C /tmp
cd /tmp/acme.sh-master
bash acme.sh install
@@ -103,10 +110,21 @@ if [ $OSNAME != "macos" ];then
fi
fi
echo "use system version: ${OSNAME}"
cd /www/server/mdserver-web && bash scripts/install/${OSNAME}.sh
if [ "${OSNAME}" == "macos" ];then
if [ "$LOCAL_ADDR" != "common" ];then
curl -fsSL https://gitee.com/midoks/mdserver-web/raw/dev/scripts/install/macos.sh | bash
else
curl -fsSL ${HTTP_PREFIX}https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install/macos.sh | bash
fi
else
cd /www/server/mdserver-web && bash scripts/install/${OSNAME}.sh
fi
if [ "${OSNAME}" == "macos" ];then
echo "macos end"
exit 0
fi
cd /www/server/mdserver-web && bash cli.sh start
isStart=`ps -ef|grep 'gunicorn -c setting.py app:app' |grep -v grep|awk '{print $2}'`
+21 -21
View File
@@ -14,26 +14,25 @@ dnf install -y python-devel
dnf install -y crontabs
dnf install -y mysql-devel
SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'`
echo "SSH PORT:${SSH_PORT}"
if [ -f /usr/sbin/iptables ];then
# if [ -f /usr/sbin/iptables ];then
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 7200 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 30000:40000 -j ACCEPT
service iptables save
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# service iptables save
iptables_status=`service iptables status | grep 'not running'`
if [ "${iptables_status}" == '' ];then
service iptables restart
fi
# iptables_status=`service iptables status | grep 'not running'`
# if [ "${iptables_status}" == '' ];then
# service iptables restart
# fi
#安装时不开启
service iptables stop
fi
# #安装时不开启
# service iptables stop
# fi
if [ ! -f /usr/sbin/iptables ];then
@@ -41,14 +40,15 @@ if [ ! -f /usr/sbin/iptables ];then
systemctl enable firewalld
systemctl start firewalld
firewall-cmd --permanent --zone=public --add-port=22/tcp
if [ "$SSH_PORT" != "" ];then
firewall-cmd --permanent --zone=public --add-port=${SSH_PORT}/tcp
else
firewall-cmd --permanent --zone=public --add-port=22/tcp
fi
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --permanent --zone=public --add-port=888/tcp
# firewall-cmd --permanent --zone=public --add-port=7200/tcp
# firewall-cmd --permanent --zone=public --add-port=3306/tcp
# firewall-cmd --permanent --zone=public --add-port=30000-40000/tcp
sed -i 's#AllowZoneDrifting=yes#AllowZoneDrifting=no#g' /etc/firewalld/firewalld.conf
firewall-cmd --reload
+23 -22
View File
@@ -21,42 +21,43 @@ yum install -y curl-devel libmcrypt libmcrypt-devel
yum install -y mysql-devel
yum install -y expect
if [ -f /usr/sbin/iptables ];then
SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'`
echo "SSH PORT:${SSH_PORT}"
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 7200 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 30000:40000 -j ACCEPT
service iptables save
# if [ -f /usr/sbin/iptables ];then
iptables_status=`service iptables status | grep 'not running'`
if [ "${iptables_status}" == '' ];then
service iptables restart
fi
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# service iptables save
#安装时不开启
service iptables stop
fi
# iptables_status=`service iptables status | grep 'not running'`
# if [ "${iptables_status}" == '' ];then
# service iptables restart
# fi
# #安装时不开启
# service iptables stop
# fi
if [ ! -f /usr/sbin/iptables ];then
if [ ! -f /usr/sbin/firewalld ];then
yum install firewalld -y
systemctl enable firewalld
#取消服务锁定
systemctl unmask firewalld
systemctl start firewalld
firewall-cmd --permanent --zone=public --add-port=22/tcp
if [ "$SSH_PORT" != "" ];then
firewall-cmd --permanent --zone=public --add-port=${SSH_PORT}/tcp
else
firewall-cmd --permanent --zone=public --add-port=22/tcp
fi
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --permanent --zone=public --add-port=888/tcp
# firewall-cmd --permanent --zone=public --add-port=7200/tcp
# firewall-cmd --permanent --zone=public --add-port=3306/tcp
# firewall-cmd --permanent --zone=public --add-port=30000-40000/tcp
sed -i 's#AllowZoneDrifting=yes#AllowZoneDrifting=no#g' /etc/firewalld/firewalld.conf
firewall-cmd --reload
+23 -22
View File
@@ -54,40 +54,41 @@ echo y | pacman -Syu icu
hwclock --systohc
if [ -f /usr/sbin/iptables ];then
SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'`
echo "SSH PORT:${SSH_PORT}"
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 7200 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 30000:40000 -j ACCEPT
service iptables save
# if [ -f /usr/sbin/iptables ];then
iptables_status=`service iptables status | grep 'not running'`
if [ "${iptables_status}" == '' ];then
service iptables restart
fi
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# service iptables save
#安装时不开启
service iptables stop
fi
# iptables_status=`service iptables status | grep 'not running'`
# if [ "${iptables_status}" == '' ];then
# service iptables restart
# fi
# #安装时不开启
# service iptables stop
# fi
if [ ! -f /usr/sbin/iptables ];then
if [ ! -f /usr/sbin/firewalld ];then
echo y | pacman -Sy firewalld
systemctl enable firewalld
systemctl start firewalld
firewall-cmd --permanent --zone=public --add-port=22/tcp
if [ "$SSH_PORT" != "" ];then
firewall-cmd --permanent --zone=public --add-port=${SSH_PORT}/tcp
else
firewall-cmd --permanent --zone=public --add-port=22/tcp
fi
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --permanent --zone=public --add-port=888/tcp
# firewall-cmd --permanent --zone=public --add-port=7200/tcp
# firewall-cmd --permanent --zone=public --add-port=3306/tcp
# firewall-cmd --permanent --zone=public --add-port=30000-40000/tcp
sed -i 's#AllowZoneDrifting=yes#AllowZoneDrifting=no#g' /etc/firewalld/firewalld.conf
firewall-cmd --reload
-6
View File
@@ -29,9 +29,6 @@ if [ -f /usr/sbin/iptables ];then
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 7200 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 30000:40000 -j ACCEPT
service iptables save
iptables_status=`service iptables status | grep 'not running'`
@@ -55,9 +52,6 @@ if [ ! -f /usr/sbin/iptables ];then
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --permanent --zone=public --add-port=888/tcp
# firewall-cmd --permanent --zone=public --add-port=7200/tcp
# firewall-cmd --permanent --zone=public --add-port=3306/tcp
# firewall-cmd --permanent --zone=public --add-port=30000-40000/tcp
sed -i 's#AllowZoneDrifting=yes#AllowZoneDrifting=no#g' /etc/firewalld/firewalld.conf
+26 -20
View File
@@ -25,63 +25,69 @@ if [ ! -z "$cn" ];then
fi
ntpdate $NTPHOST | logger -t NTP
SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'`
echo "SSH PORT:${SSH_PORT}"
# choose lang cmd
# dpkg-reconfigure --frontend=noninteractive locales
if [ ! -f /usr/sbin/locale-gen ];then
apt install -y locales
sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen
locale-gen en_US.UTF-8
localedef -v -c -i en_US -f UTF-8 en_US.UTF-8
dpkg-reconfigure --frontend=noninteractive locales
localedef -v -c -i en_US -f UTF-8 en_US.UTF-8 > /dev/null 2>&1
update-locale LANG=en_US.UTF-8
else
locale-gen en_US.UTF-8
localedef -v -c -i en_US -f UTF-8 en_US.UTF-8
localedef -v -c -i en_US -f UTF-8 en_US.UTF-8 > /dev/null 2>&1
fi
apt-get update -y
apt install -y wget curl lsof unzip tar cron expect locate
apt install -y python3-pip python3-dev python3-venv
if [ -f /usr/sbin/ufw ];then
ufw allow 22/tcp
if [ -f /usr/sbin/ufw ];then
# look
# ufw status
ufw enable
if [ "$SSH_PORT" != "" ];then
ufw allow $SSH_PORT/tcp
else
ufw allow 22/tcp
fi
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 888/tcp
# ufw allow 7200/tcp
# ufw allow 3306/tcp
# ufw allow 30000:40000/tcp
fi
if [ -f /usr/sbin/ufw ];then
ufw disable
fi
if [ ! -f /usr/sbin/ufw ];then
# look
# firewall-cmd --list-all
# apt remove -y firewalld
apt install -y firewalld
systemctl enable firewalld
#取消服务锁定
systemctl unmask firewalld
systemctl start firewalld
firewall-cmd --permanent --zone=public --add-port=22/tcp
if [ "$SSH_PORT" != "" ];then
firewall-cmd --permanent --zone=public --add-port=${SSH_PORT}/tcp
else
firewall-cmd --permanent --zone=public --add-port=22/tcp
fi
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --permanent --zone=public --add-port=888/tcp
# firewall-cmd --permanent --zone=public --add-port=7200/tcp
# firewall-cmd --permanent --zone=public --add-port=3306/tcp
# firewall-cmd --permanent --zone=public --add-port=30000-40000/tcp
systemctl start firewalld
# fix:debian10 firewalld faq
# https://kawsing.gitbook.io/opensystem/andoid-shou-ji/untitled/fang-huo-qiang#debian-10-firewalld-0.6.3-error-commandfailed-usrsbinip6tablesrestorewn-failed-ip6tablesrestore-v1.8
sed -i 's#IndividualCalls=no#IndividualCalls=yes#g' /etc/firewalld/firewalld.conf
firewall-cmd --reload
#安装时不开启
systemctl stop firewalld
fi
#fix zlib1g-dev fail
+32 -29
View File
@@ -17,45 +17,48 @@ yum install -y wget curl lsof unzip
yum install -y expect
dnf install crontabs -y
if [ -f /usr/sbin/iptables ];then
SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'`
echo "SSH PORT:${SSH_PORT}"
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 7200 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 30000:40000 -j ACCEPT
service iptables save
# if [ -f /usr/sbin/iptables ];then
iptables_status=`service iptables status | grep 'not running'`
if [ "${iptables_status}" == '' ];then
service iptables restart
fi
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# # iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 7200 -j ACCEPT
# # iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
# # iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 30000:40000 -j ACCEPT
# service iptables save
#安装时不开启
service iptables stop
fi
# iptables_status=`service iptables status | grep 'not running'`
# if [ "${iptables_status}" == '' ];then
# service iptables restart
# fi
# #安装时不开启
# service iptables stop
# fi
if [ ! -f /usr/sbin/iptables ];then
yum install firewalld -y
systemctl enable firewalld
systemctl start firewalld
if [ "${isVersion}" == '' ];then
if [ ! -f "/usr/sbin/iptables" ];then
yum install firewalld -y
systemctl enable firewalld
systemctl start firewalld
if [ "$SSH_PORT" != "" ];then
firewall-cmd --permanent --zone=public --add-port=${SSH_PORT}/tcp
else
firewall-cmd --permanent --zone=public --add-port=22/tcp
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --permanent --zone=public --add-port=888/tcp
# firewall-cmd --permanent --zone=public --add-port=7200/tcp
# firewall-cmd --permanent --zone=public --add-port=3306/tcp
# firewall-cmd --permanent --zone=public --add-port=30000-40000/tcp
firewall-cmd --reload
fi
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --permanent --zone=public --add-port=888/tcp
firewall-cmd --reload
fi
#安装时不开启
systemctl stop firewalld
+21 -23
View File
@@ -39,39 +39,40 @@ pkg install -y harfbuzz
pkg autoremove -y
if [ -f /usr/sbin/iptables ];then
SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'`
echo "SSH PORT:${SSH_PORT}"
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 7200 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 30000:40000 -j ACCEPT
service iptables save
# if [ -f /usr/sbin/iptables ];then
iptables_status=`service iptables status | grep 'not running'`
if [ "${iptables_status}" == '' ];then
service iptables restart
fi
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# service iptables save
#安装时不开启
service iptables stop
fi
# iptables_status=`service iptables status | grep 'not running'`
# if [ "${iptables_status}" == '' ];then
# service iptables restart
# fi
# #安装时不开启
# service iptables stop
# fi
if [ ! -f /usr/sbin/iptables ];then
pkg install -y firewalld
systemctl enable firewalld
systemctl start firewalld
firewall-cmd --permanent --zone=public --add-port=22/tcp
if [ "$SSH_PORT" != "" ];then
firewall-cmd --permanent --zone=public --add-port=${SSH_PORT}/tcp
else
firewall-cmd --permanent --zone=public --add-port=22/tcp
fi
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --permanent --zone=public --add-port=888/tcp
# firewall-cmd --permanent --zone=public --add-port=7200/tcp
# firewall-cmd --permanent --zone=public --add-port=3306/tcp
# firewall-cmd --permanent --zone=public --add-port=30000-40000/tcp
sed -i 's#AllowZoneDrifting=yes#AllowZoneDrifting=no#g' /etc/firewalld/firewalld.conf
@@ -80,9 +81,6 @@ if [ ! -f /usr/sbin/iptables ];then
systemctl stop firewalld
fi
cd /www/server/mdserver-web/scripts && bash lib.sh
chmod 755 /www/server/mdserver-web/data
-4
View File
@@ -36,8 +36,6 @@ if [ ! -d $DEV/server/lib ]; then
cd $DEV/server/mdserver-web/scripts && bash lib.sh
fi
pip3 install mysqlclient
chmod 755 $DEV/server/mdserver-web/data
if [ -f $DEV/server/mdserver-web/bin/activate ];then
cd $DEV/server/mdserver-web && python3 -m venv $DEV/server/mdserver-web
@@ -47,8 +45,6 @@ else
cd $DEV/server/mdserver-web && pip3 install -r $DEV/server/mdserver-web/requirements.txt
fi
pip3 install mysqlclient
cd $DEV/server/mdserver-web && ./cli.sh start
cd $DEV/server/mdserver-web && ./cli.sh stop
+23 -22
View File
@@ -52,40 +52,41 @@ zypper install -y freetype2-devel
# zypper install -y php-config
if [ -f /usr/sbin/iptables ];then
SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'`
echo "SSH PORT:${SSH_PORT}"
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 7200 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 30000:40000 -j ACCEPT
service iptables save
# if [ -f /usr/sbin/iptables ];then
iptables_status=`service iptables status | grep 'not running'`
if [ "${iptables_status}" == '' ];then
service iptables restart
fi
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# service iptables save
#安装时不开启
service iptables stop
fi
# iptables_status=`service iptables status | grep 'not running'`
# if [ "${iptables_status}" == '' ];then
# service iptables restart
# fi
# #安装时不开启
# service iptables stop
# fi
if [ ! -f /usr/sbin/iptables ];then
if [ ! -f /usr/sbin/firewalld ];then
zypper install -y firewalld
systemctl enable firewalld
systemctl start firewalld
firewall-cmd --permanent --zone=public --add-port=22/tcp
if [ "$SSH_PORT" != "" ];then
firewall-cmd --permanent --zone=public --add-port=${SSH_PORT}/tcp
else
firewall-cmd --permanent --zone=public --add-port=22/tcp
fi
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --permanent --zone=public --add-port=888/tcp
# firewall-cmd --permanent --zone=public --add-port=7200/tcp
# firewall-cmd --permanent --zone=public --add-port=3306/tcp
# firewall-cmd --permanent --zone=public --add-port=30000-40000/tcp
sed -i 's#AllowZoneDrifting=yes#AllowZoneDrifting=no#g' /etc/firewalld/firewalld.conf
firewall-cmd --reload
+48 -35
View File
@@ -33,55 +33,65 @@ if [ ! -d /root/.acme.sh ];then
curl https://get.acme.sh | sh
fi
echo "iptables wrap start"
if [ -f /usr/sbin/iptables ];then
$PKGMGR install -y iptables-services
SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'`
echo "SSH PORT:${SSH_PORT}"
# iptables -nL --line-number
# redhat , iptables no default
# echo "iptables wrap start"
# if [ -f /usr/sbin/iptables ];then
# $PKGMGR install -y iptables-services
# # iptables -nL --line-number
echo "iptables start"
iptables_status=`systemctl status iptables | grep 'inactive'`
if [ "${iptables_status}" != '' ];then
service iptables restart
# echo "iptables start"
# iptables_status=`systemctl status iptables | grep 'inactive'`
# if [ "${iptables_status}" != '' ];then
# service iptables restart
# iptables -P FORWARD DROP
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -p tcp -s 127.0.0.1 -j ACCEPT
# # iptables -P FORWARD DROP
# iptables -P INPUT DROP
# iptables -P OUTPUT ACCEPT
# iptables -A INPUT -p tcp -s 127.0.0.1 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 7200 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 30000:40000 -j ACCEPT
service iptables save
fi
# if [ "$SSH_PORT" != "" ];then
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${SSH_PORT} -j ACCEPT
# else
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# fi
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 888 -j ACCEPT
# # iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 7200 -j ACCEPT
# # iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
# # iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 30000:40000 -j ACCEPT
# service iptables save
# fi
# 安装时不开启
# stop之后清空了所有规则,所以安装是不能stop.
# 要在代码修复这个问题,开启时,重新执行一下放行端口。
#service iptables stop
# # 安装时不开启
# # stop之后清空了所有规则,所以安装是不能stop.
# # 要在代码修复这个问题,开启时,重新执行一下放行端口。
# #service iptables stop
echo "iptables end"
fi
echo "iptables wrap start"
# echo "iptables end"
# fi
# echo "iptables wrap start"
if [ ! -f /usr/sbin/iptables ];then
if [ ! -f /usr/sbin/firewalld ];then
$PKGMGR install firewalld -y
systemctl enable firewalld
#取消服务锁定
systemctl unmask firewalld
systemctl start firewalld
sed -i 's#AllowZoneDrifting=yes#AllowZoneDrifting=no#g' /etc/firewalld/firewalld.conf
firewall-cmd --reload
# look
# firewall-cmd --list-all
firewall-cmd --permanent --zone=public --add-port=22/tcp
if [ "$SSH_PORT" != "" ];then
firewall-cmd --permanent --zone=public --add-port=${SSH_PORT}/tcp
else
firewall-cmd --permanent --zone=public --add-port=22/tcp
fi
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --permanent --zone=public --add-port=888/tcp
@@ -89,7 +99,7 @@ if [ ! -f /usr/sbin/iptables ];then
# firewall-cmd --permanent --zone=public --add-port=3306/tcp
# firewall-cmd --permanent --zone=public --add-port=30000-40000/tcp
# sed -i 's#AllowZoneDrifting=yes#AllowZoneDrifting=no#g' /etc/firewalld/firewalld.conf
sed -i 's#AllowZoneDrifting=yes#AllowZoneDrifting=no#g' /etc/firewalld/firewalld.conf
firewall-cmd --reload
#安装时不开启
@@ -121,11 +131,14 @@ if [ $VERSION_ID -ge 8 ];then
gmp-devel kernel-devel libXpm-devel libaio-devel libcap libcurl libcurl-devel libevent libevent-devel \
libicu-devel libidn libidn-devel libmcrypt libmcrypt-devel libmemcached libmemcached-devel \
libpng libpng-devel libstdc++.so.6 libtirpc libtirpc-devel libtool libtool-libs libwebp libwebp-devel \
libxml2 libxml2-devel libxslt libxslt-devel lsof make mysql-devel ncurses ncurses-devel net-tools \
libxml2 libxml2-devel libxslt libxslt-devel libarchive lsof make mysql-devel ncurses ncurses-devel net-tools \
oniguruma oniguruma-devel patch pcre pcre-devel perl perl-Data-Dumper perl-devel procps psmisc python3-devel \
readline-devel rpcgen sqlite-devel tar unzip vim-minimal wget zip zlib zlib-devel ;
do
dnf $REPOS install -y $rpms;
if [ "$?" != "0" ];then
dnf install -y $rpms;
fi
done
else
# CentOS 7
+23 -19
View File
@@ -24,48 +24,52 @@ apt install -y locate
locale-gen en_US.UTF-8
localedef -v -c -i en_US -f UTF-8 en_US.UTF-8
SSH_PORT=`netstat -ntpl|grep sshd|grep -v grep | sed -n "1,1p" | awk '{print $4}' | awk -F : '{print $2}'`
echo "SSH PORT:${SSH_PORT}"
if [ -f /usr/sbin/ufw ];then
# look
# ufw status
ufw enable
if [ "$SSH_PORT" != "" ];then
ufw allow $SSH_PORT/tcp
else
ufw allow 22/tcp
fi
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 888/tcp
# ufw allow 7200/tcp
# ufw allow 3306/tcp
# ufw allow 30000:40000/tcp
fi
if [ -f /usr/sbin/ufw ];then
ufw disable
fi
if [ ! -f /usr/sbin/ufw ];then
apt install -y firewalld
systemctl enable firewalld
systemctl start firewalld
if [ "$SSH_PORT" != "" ];then
firewall-cmd --permanent --zone=public --add-port=${SSH_PORT}/tcp
else
firewall-cmd --permanent --zone=public --add-port=22/tcp
fi
firewall-cmd --permanent --zone=public --add-port=22/tcp
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --permanent --zone=public --add-port=888/tcp
# firewall-cmd --permanent --zone=public --add-port=7200/tcp
# firewall-cmd --permanent --zone=public --add-port=3306/tcp
# firewall-cmd --permanent --zone=public --add-port=30000-40000/tcp
systemctl start firewalld
# fix:debian10 firewalld faq
# https://kawsing.gitbook.io/opensystem/andoid-shou-ji/untitled/fang-huo-qiang#debian-10-firewalld-0.6.3-error-commandfailed-usrsbinip6tablesrestorewn-failed-ip6tablesrestore-v1.8
sed -i 's#IndividualCalls=no#IndividualCalls=yes#g' /etc/firewalld/firewalld.conf
firewall-cmd --reload
# #安装时不开启
# systemctl stop firewalld
fi
#安装时不开启
systemctl stop firewalld
apt install -y devscripts
apt install -y net-tools
apt install -y python3-dev
+40 -5
View File
@@ -5,7 +5,7 @@ export PATH
is64bit=`getconf LONG_BIT`
echo -e "您正在安装的是\033[31mmdserver-web测试版\033[0m,非开发测试用途请使用正式版 install.sh !"
echo -e "You are installing\033[31mmdserver-web dev version\033[0m, normally use install.sh for production.\n"
echo -e "You are installing\033[31m mdserver-web dev version\033[0m, normally use install.sh for production.\n"
sleep 1
{
@@ -60,6 +60,20 @@ else
fi
HTTP_PREFIX="https://"
LOCAL_ADDR=common
ping -c 1 github.com > /dev/null 2>&1
if [ "$?" != "0" ];then
LOCAL_ADDR=cn
HTTP_PREFIX="https://ghproxy.com/"
fi
# cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
# HTTP_PREFIX="https://"
# if [ ! -z "$cn" ];then
# HTTP_PREFIX="https://ghproxy.com/"
# fi
if [ $OSNAME != "macos" ];then
mkdir -p /www/server
mkdir -p /www/wwwroot
@@ -68,7 +82,13 @@ if [ $OSNAME != "macos" ];then
mkdir -p /www/backup/site
if [ ! -d /www/server/mdserver-web ];then
curl -sSLo /tmp/dev.zip https://github.com/midoks/mdserver-web/archive/refs/heads/dev.zip
if [ "$LOCAL_ADDR" == "common" ];then
curl -sSLo /tmp/dev.zip ${HTTP_PREFIX}github.com/midoks/mdserver-web/archive/refs/heads/dev.zip
else
curl -sSLo /tmp/dev.zip https://gitee.com/midoks/mdserver-web/repository/archive/dev.zip
fi
cd /tmp && unzip /tmp/dev.zip
mv -f /tmp/mdserver-web-dev /www/server/mdserver-web
rm -rf /tmp/dev.zip
@@ -77,8 +97,9 @@ if [ $OSNAME != "macos" ];then
# install acme.sh
if [ ! -d /root/.acme.sh ];then
if [ ! -z "$cn" ];then
curl -sSL -o /tmp/acme.tar.gz https://ghproxy.com/github.com/acmesh-official/acme.sh/archive/master.tar.gz
if [ "$LOCAL_ADDR" != "common" ];then
# curl -sSL -o /tmp/acme.tar.gz ${HTTP_PREFIX}github.com/acmesh-official/acme.sh/archive/master.tar.gz
curl -sSLo /tmp/acme.tar.gz https://gitee.com/neilpang/acme.sh/repository/archive/master.tar.gz
tar xvzf /tmp/acme.tar.gz -C /tmp
cd /tmp/acme.sh-master
bash acme.sh install
@@ -92,7 +113,21 @@ if [ $OSNAME != "macos" ];then
fi
echo "use system version: ${OSNAME}"
cd /www/server/mdserver-web && bash scripts/install/${OSNAME}.sh
if [ "${OSNAME}" == "macos" ];then
if [ "$LOCAL_ADDR" != "common" ];then
curl -fsSL https://gitee.com/midoks/mdserver-web/raw/dev/scripts/install/macos.sh | bash
else
curl -fsSL ${HTTP_PREFIX}https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install/macos.sh | bash
fi
else
cd /www/server/mdserver-web && bash scripts/install/${OSNAME}.sh
fi
if [ "${OSNAME}" == "macos" ];then
echo "macos end"
exit 0
fi
cd /www/server/mdserver-web && bash cli.sh start
isStart=`ps -ef|grep 'gunicorn -c setting.py app:app' |grep -v grep|awk '{print $2}'`
+10 -2
View File
@@ -47,9 +47,17 @@ else
echo "OK"
fi
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
# cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
HTTP_PREFIX="https://"
LOCAL_ADDR=common
ping -c 1 github.com > /dev/null 2>&1
if [ "$?" != "0" ];then
LOCAL_ADDR=cn
HTTP_PREFIX="https://ghproxy.com/"
fi
PIPSRC="https://pypi.python.org/simple"
if [ ! -z "$cn" ];then
if [ "$LOCAL_ADDR" != "common" ];then
PIPSRC="https://pypi.tuna.tsinghua.edu.cn/simple"
fi

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