From 896c4a36e6b6fd38b275e31aaccfe46af56c1adc Mon Sep 17 00:00:00 2001 From: er10yi Date: Sun, 11 Oct 2020 01:10:40 +0800 Subject: [PATCH] 2.0.2 --- README.md | 34 ++---- deploy/MagiCude/dist/index.html | 2 +- .../dist/static/js/chunk-67130b18.31033bc9.js | 1 - .../dist/static/js/chunk-67130b18.4e9bc052.js | 1 + .../operation/checkDockerImageStatus.sh | 2 +- .../MagiCude/operation/dockerStopService.sh | 4 +- deploy/MagiCude/operation/restartAll.sh | 16 +-- deploy/MagiCude/operation/stopAll.sh | 22 ++-- .../MagiCude/operation/stopCenterService.sh | 4 +- deploy/defaultConf/agent.yml | 2 +- .../initAgentEnvironmentAndStart.sh | 91 +++++++++++---- .../initCenterEnvironmentAndStart.sh | 94 ++++++++++------ deploy/defaultConf/magicude | 10 +- deploy/defaultConf/magicude.sql | 53 --------- deploy/defaultConf/stopAgent.sh | 2 +- deploy/defaultConf/uninstall.sh | 105 ++++++++++++++++++ deploy/defaultConf/util.sh | 8 +- ...77\347\224\250\350\257\264\346\230\216.md" | 65 +++-------- .../\351\200\211\346\213\251ip.png" | Bin 0 -> 41340 bytes 19 files changed, 297 insertions(+), 219 deletions(-) delete mode 100644 deploy/MagiCude/dist/static/js/chunk-67130b18.31033bc9.js create mode 100644 deploy/MagiCude/dist/static/js/chunk-67130b18.4e9bc052.js create mode 100644 deploy/defaultConf/uninstall.sh create mode 100644 "\344\275\277\347\224\250\350\257\264\346\230\216\345\233\2761/\351\200\211\346\213\251ip.png" diff --git a/README.md b/README.md index ca0a2f5..44b8281 100644 --- a/README.md +++ b/README.md @@ -28,41 +28,23 @@ by [贰拾壹](https://github.com/er10yi ) 假设服务器已装好,服务器ip地址为```192.168.12.128``` -## 四步快速部署 +## 三步快速部署 ### 1.生成配置文件 下载部署包(Releases页面)解压后,deploy目录下双击```GenPass.bat```(Windows下,*uinx/mac直接执行```GenPass.bat```里面的内容就行了),将在当前目录生成newPass.txt,新的配置文件和初始化脚本会自动复制到MagiCude目录下 -### 2.修改前端api接口地址及agent.yml +### 2.将deploy目录下的MagiCude上传到服务器root目录下 -#### 前端api接口地址 +### 3.初始化环境并运行系统 -需要修改```MagiCude\dist\static\js\app.*.js```,* 指的是类似ea5c35e2这样一串字符 - -将baseURL:```"http://127.0.0.1:9001/"```中的ip改成实际部署服务器的ip - -如 ```baseURL:"http://192.168.12.128:9001/"``` - -#### agent.yml - -需要修改```MagiCude```目录下的agent.yml中center节点的ip地址 - -```yml -center: - httpValidateApi: http://127.0.0.1:9001/center/pluginchecker # 需要修改成部署centerapp.jar服务器的ip - dnsValidateIp: 127.0.0.1 # 需要修改成部署centerapp.jar服务器的ip -``` - -将127.0.0.1改成实际部署centerapp.jar服务器的ip - -如 ```dnsValidateIp: 192.168.12.128``` +终端执行```sh initCenterEnvironmentAndStart.sh```,初始化环境和数据并启动系统 -### 3.将deploy目录下的MagiCude上传到服务器root目录下 +**需要手动选择center的ip地址** -### 4.初始化环境并运行系统 +![选择ip](./使用说明图1/选择ip.png) -终端执行```sh initCenterEnvironmentAndStart.sh```,初始化环境和数据并启动系统 +安装结束时,如果没有错误信息,则成功安装 ## 其他 @@ -97,7 +79,7 @@ center: 密码:见newPass.txt ``` -### 任务信息-Agent +任务信息-Agent,看到agent在线即可 ![agent在线](./使用说明图1/agent在线.png) ## 微信讨论组 diff --git a/deploy/MagiCude/dist/index.html b/deploy/MagiCude/dist/index.html index 2bdf6b4..1c92da5 100644 --- a/deploy/MagiCude/dist/index.html +++ b/deploy/MagiCude/dist/index.html @@ -1 +1 @@ -魔方-MagiCude
\ No newline at end of file +魔方-MagiCude
\ No newline at end of file diff --git a/deploy/MagiCude/dist/static/js/chunk-67130b18.31033bc9.js b/deploy/MagiCude/dist/static/js/chunk-67130b18.31033bc9.js deleted file mode 100644 index f2cb6a0..0000000 --- a/deploy/MagiCude/dist/static/js/chunk-67130b18.31033bc9.js +++ /dev/null @@ -1 +0,0 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-67130b18"],{"10dd":function(t,i,l){"use strict";var a=l("ec3b"),e=l.n(a);e.a},ec3b:function(t,i,l){},ef46:function(t,i,l){"use strict";l.r(i);var a=function(){var t=this,i=t.$createElement,l=t._self._c||i;return l("div",{staticStyle:{padding:"100px 200px 0"}},[l("el-card",{staticClass:"box-card"},[l("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[l("span",[l("b",[t._v("魔方-MagiCude")])]),l("el-link",{attrs:{underline:!1},on:{click:function(i){return t.handleDrawer()}}},[l("i",{staticClass:"el-icon-view el-icon--right"}),t._v("正式版 V2.0.1 ")]),l("el-link",{staticStyle:{float:"right"},attrs:{href:"https://github.com/er10yi/MagiCude",target:"_blank"}},[t._v("GitHub项目页面")])],1),l("div",{staticClass:"text"},[l("ol",[l("li",[t._v("高效获取服务器IP, 端口信息, web信息, url链接, 漏洞等资产信息")]),l("li",[t._v("对资产进行有效的安全管理")]),l("li",[t._v("建立漏洞wiki并自动闭环漏洞, 减少安全部门与业务部门的沟通")]),l("li",[t._v("即时漏洞提醒")]),l("li",[t._v("定时发送资产报告和漏洞报告")]),l("li",[t._v("及时发送资产信息和处理结果给负责人进行整改并自动确认整改完成")]),l("li",[t._v("有效获取DHCP的办公机IP与用户关联")]),l("li",[t._v("丰富的图表统计")]),l("li",[t._v("POC框架")])])]),l("div",{staticClass:"item"},[t._v(" Copyrights © 2018-"+t._s(t.getYear())+" "),l("el-link",{attrs:{type:"info",href:"https://github.com/er10yi",target:"_blank"}},[t._v("贰拾壹.")]),t._v("All Rights Reserved. ")],1)]),l("el-drawer",{attrs:{title:"ChangeLog",visible:t.drawer,direction:"rtl",size:"60%",beforeclose:t.handleDrawerClose},on:{"update:visible":function(i){t.drawer=i}}},[l("el-card",{staticClass:"box-card"},[l("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[l("span",[l("b",[t._v("TDL - 待定")])]),l("div",{staticClass:"text"},[l("ol",[l("li",[t._v("增加用户前端,放开漏洞wiki,还有啥?")]),l("li",[t._v("丰富漏洞wiki,建成知识库")]),l("li",[t._v("增加全局搜索")]),l("li",[t._v("增加资产导入接口,漏洞导入接口")])])])])]),l("el-card",{staticClass:"box-card"},[l("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[l("span",[l("b",[t._v("正式版 V2.0.1 - 20201009")])]),l("div",{staticClass:"text"},[l("ol",[t._v(" 部署脚本: "),l("li",[t._v("增加部署脚本执行目录判断(issues #3 建议判断或约束一下安装脚本执行目录)")]),l("li",[t._v("增加agent.yml内容是否已经修改判断")]),l("li",[t._v("增加center和agent所需文件判断")]),l("li",[t._v("增加前端api地址是否修改判断")]),l("li",[t._v("增加操作系统判断")]),l("li",[t._v("修复多次重新部署的时候,环境变量会写入多次")]),l("li",[t._v("优化脚本日志输出,屏蔽非脚本错误输出,优化所有脚本")]),l("li",[t._v("Python升级到3.9.0")]),l("li",[t._v("部署脚本运行结束时,增加信息和错误提示")]),l("li",[t._v("移除agentDependency,nmap更新到7.90")])])])])]),l("el-card",{staticClass:"box-card"},[l("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[l("span",[l("b",[t._v("正式版 V2.0 - 20200925")])]),l("div",{staticClass:"text"},[l("ol",[t._v(" 正式版发布,同时开源 ")])])])]),l("el-card",{staticClass:"box-card"},[l("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[l("span",[l("b",[t._v("公测版 V1.3.25 - 20200913")])]),l("div",{staticClass:"text"},[l("ol",[t._v(" 前端: "),l("li",[t._v("修复 子任务Drawer,调整分页无效的问题")]),l("li",[t._v("优化 用code标签显示代码")]),l("li",[t._v("新增 插件页面新增插件代码高亮,python3的selfd插件可前端新增(已知bug,第一次进入插件页面,新增或编辑需要打开两次代码高亮插件才会正常显示,第二次保存才能正常添加代码)")]),l("li",[t._v("新增 设置-批量导入,新增python3的selfd插件配置导入,主要用于python3的selfd插件配置及代码导入")]),l("li",[t._v("新增 新增各个类型任务的demo")]),t._v(" 后端: "),l("li",[t._v("修复 nse类型任务,获取状态时不显示PID信息")]),l("li",[t._v("修复 nse、selfd、httpp任务,资产库无对应的信息时,任务也会发给agent")]),l("li",[t._v("修复 无资产ip时,目标ip为ipNoPort,unknownPortSerVer,ipAllPort,任务也会发给agent")]),l("li",[t._v("修复 修复插件未设置服务和版本时,启动任务会开启所有插件 ")]),l("li",[t._v("优化 优化新增自定义插件,插件核心增加Jep方式调用python代码,可前端直接新增python3的selfd自定义类型的插件(重要更新,TDL的一半,优化新增自定义插件并丰富插件)")]),l("li",[t._v("优化 优化全部批量删除")]),l("li",[t._v("新增 新增python3的selfd插件配置导入接口")]),l("li",[t._v("新增 agent新增python插件import检测,如模块未安装,则会自动安装")]),l("li",[t._v("新增 插件配置新增http、dns辅助验证,用于插件辅助验证无回显漏洞(TDL 增加无回显插件检测)")]),l("li",[t._v("新增 增加HTTP json插件解析")]),l("li",[t._v("修改 随机获取ua的方式修改,存入redis进行随机")]),t._v(" 数据库: "),l("li",[t._v("新增 插件配置新增plugincode字段,用于保存插件代码")]),l("li",[t._v("新增 插件配置新增validatetype字段,用于开启插件http辅助验证或dns辅助验证")]),t._v(" 配置文件: "),l("li",[t._v("新增 agent.yml新增jep节点,用于保存JEP本地库的绝对路径")]),l("li",[t._v("新增 agent.yml新增center节点,用于插件辅助验证时传递http接口和dns的ip地址")]),t._v(" 部署脚本: "),l("li",[t._v("增加 新增Python3.8编译安装")]),l("li",[t._v("移除 移除jre14,修改成jdk15(JEP编译需要)")]),t._v(" 文档: "),l("li",[t._v("优化 优化快速上手及说明文档")]),l("li",[t._v("增加 新增Readme文档")]),l("li",[t._v("增加 新增插件编写说明")])])])])]),l("el-card",{staticClass:"box-card"},[l("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[l("span",[l("b",[t._v("公测版 V1.2.2 - 20200722")])]),l("div",{staticClass:"text"},[l("ol",[l("li",[t._v("优化center部署脚本,增加判断是否已经运行过部署脚本,避免误操作二次运行部署脚本(如果已经部署,则需要用户交互),优化docker服务运行状态检测")]),l("li",[t._v("优化initDataAndStart.sh,增加脚本复制和执行成功的判断")]),l("li",[t._v("修改center.yml,token过期时间设置成一小时")]),l("li",[t._v("优化任务插件显示,将插件启用状态体现到操作中,优化插件启用禁用")]),l("li",[t._v("新增子任务展开Drawer")]),l("li",[t._v("about页面版本上增加changelog的Drawer,增加更新日志及TDL")]),l("li",[t._v("前端依赖更新到最新")])])])])]),l("el-card",{staticClass:"box-card"},[l("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[l("span",[l("b",[t._v("公测版 V1.2.1 - 20200715")])]),l("div",{staticClass:"text"},[l("ol",[t._v(" 前端: "),l("li",[t._v("增加about页面")]),l("li",[t._v("增加菜单栏显示与隐藏的Collapse,涉及的页面:任务、资产ip、资产端口、主机、检测结果、web信息、web信息和url")]),l("li",[t._v("优化资产ip,去除编辑页面显示ip所有信息,修改成Drawer方式显示,并增加url超链接")]),l("li",[t._v("优化资产端口,去除编辑页面显示端口所有信息,修改成Drawer方式显示,并增加http和https链接打开,增加url超链接")]),l("li",[t._v("优化新建任务的数量前端样式,将input修改成number模式")]),l("li",[t._v("优化检测类型任务,将input修改成单选模式")]),l("li",[t._v("优化web信息中ip的显示,增加打开http和https链接的Popover")]),l("li",[t._v("首页四个折线图修改成显示最新数据的10%")]),l("li",[t._v("修改设置-通知设置中的风险等级编辑样式,从input改成单选模式")]),l("li",[t._v("修改cron表达式解析结果的样式,改成表格")])])])])]),l("el-card",{staticClass:"box-card"},[l("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[l("span",[l("b",[t._v("公测版 V1.2.0 - 20200706")])]),l("div",{staticClass:"text"},[l("ol",[t._v(" 公开公测开启 ")])])])]),l("el-card",{staticClass:"box-card"},[l("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[l("span",[l("b",[t._v("内测版 V1.1 - 20200615")])]),l("div",{staticClass:"text"},[l("ol",[l("li",[t._v("优化部署步骤,修改部署脚本成一键部署")]),l("li",[t._v("部署脚本增加系统源修改判断和docker镜像源修改判断(需要用户交互)")]),l("li",[t._v("部署脚本增加判断,提高安装部署成功率")]),l("li",[t._v("前端增加web信息功能,后端优化部分代码")]),l("li",[t._v("文档增加Q/A章节、微信公众号、项目的目录结构说明,为公测做准备")]),l("li",[t._v("增加公测宣传文档")]),l("li",[t._v("增加magicude执行脚本,便于查看系统状态及操作系统(0624)")])])])])]),l("el-card",{staticClass:"box-card"},[l("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[l("span",[l("b",[t._v("内测版 V1.0 - 20200528")])]),l("div",{staticClass:"text"},[l("ol",[t._v(" 公开内测开启 ")])])])])],1)],1)},e=[],s={data:function(){return{drawer:!1}},methods:{handleDrawer:function(){this.drawer=!0},handleDrawerClose:function(){this.drawer=!1},getYear:function(){var t=new Date;return this.year=t.getFullYear(),this.year}}},r=s,v=(l("10dd"),l("2877")),d=Object(v["a"])(r,a,e,!1,null,null,null);i["default"]=d.exports}}]); \ No newline at end of file diff --git a/deploy/MagiCude/dist/static/js/chunk-67130b18.4e9bc052.js b/deploy/MagiCude/dist/static/js/chunk-67130b18.4e9bc052.js new file mode 100644 index 0000000..dc53376 --- /dev/null +++ b/deploy/MagiCude/dist/static/js/chunk-67130b18.4e9bc052.js @@ -0,0 +1 @@ +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-67130b18"],{"10dd":function(t,l,i){"use strict";var a=i("ec3b"),e=i.n(a);e.a},ec3b:function(t,l,i){},ef46:function(t,l,i){"use strict";i.r(l);var a=function(){var t=this,l=t.$createElement,i=t._self._c||l;return i("div",{staticStyle:{padding:"100px 200px 0"}},[i("el-card",{staticClass:"box-card"},[i("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[i("span",[i("b",[t._v("魔方-MagiCude")])]),i("el-link",{attrs:{underline:!1},on:{click:function(l){return t.handleDrawer()}}},[i("i",{staticClass:"el-icon-view el-icon--right"}),t._v("正式版 V2.0.2 ")]),i("el-link",{staticStyle:{float:"right"},attrs:{href:"https://github.com/er10yi/MagiCude",target:"_blank"}},[t._v("GitHub项目页面")])],1),i("div",{staticClass:"text"},[i("ol",[i("li",[t._v("高效获取服务器IP, 端口信息, web信息, url链接, 漏洞等资产信息")]),i("li",[t._v("对资产进行有效的安全管理")]),i("li",[t._v("建立漏洞wiki并自动闭环漏洞, 减少安全部门与业务部门的沟通")]),i("li",[t._v("即时漏洞提醒")]),i("li",[t._v("定时发送资产报告和漏洞报告")]),i("li",[t._v("及时发送资产信息和处理结果给负责人进行整改并自动确认整改完成")]),i("li",[t._v("有效获取DHCP的办公机IP与用户关联")]),i("li",[t._v("丰富的图表统计")]),i("li",[t._v("POC框架")])])]),i("div",{staticClass:"item"},[t._v(" Copyrights © 2018-"+t._s(t.getYear())+" "),i("el-link",{attrs:{type:"info",href:"https://github.com/er10yi",target:"_blank"}},[t._v("贰拾壹.")]),t._v("All Rights Reserved. ")],1)]),i("el-drawer",{attrs:{title:"ChangeLog",visible:t.drawer,direction:"rtl",size:"60%",beforeclose:t.handleDrawerClose},on:{"update:visible":function(l){t.drawer=l}}},[i("el-card",{staticClass:"box-card"},[i("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[i("span",[i("b",[t._v("TDL - 待定")])]),i("div",{staticClass:"text"},[i("ol",[i("li",[t._v("增加用户前端,放开漏洞wiki,还有啥?")]),i("li",[t._v("丰富漏洞wiki,建成知识库")]),i("li",[t._v("增加全局搜索")]),i("li",[t._v("增加资产导入接口,漏洞导入接口")])])])])]),i("el-card",{staticClass:"box-card"},[i("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[i("span",[i("b",[t._v("正式版 V2.0.2 - 20201011")])]),i("div",{staticClass:"text"},[i("ol",[t._v(" 部署脚本: "),i("li",[t._v("日志提示增加字体颜色")]),i("li",[t._v("增加卸载脚本")]),i("li",[t._v("center部署无需本地手动修改前端api地址和agent.yml中的地址,只需部署时选择即可")]),i("li",[t._v("agent分布式部署无需本地手动修改agent.yml中的地址,只需部署时输入部署center的ip地址即可")]),i("li",[t._v("优化判断依赖是否存在的方式")])])])])]),i("el-card",{staticClass:"box-card"},[i("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[i("span",[i("b",[t._v("正式版 V2.0.1 - 20201009")])]),i("div",{staticClass:"text"},[i("ol",[t._v(" 部署脚本: "),i("li",[t._v("增加部署脚本执行目录判断(issues #3 建议判断或约束一下安装脚本执行目录)")]),i("li",[t._v("增加agent.yml内容是否已经修改判断")]),i("li",[t._v("增加center和agent所需文件判断")]),i("li",[t._v("增加前端api地址是否修改判断")]),i("li",[t._v("增加操作系统判断")]),i("li",[t._v("修复多次重新部署的时候,环境变量会写入多次")]),i("li",[t._v("优化脚本日志输出,屏蔽非脚本错误输出,优化所有脚本")]),i("li",[t._v("Python升级到3.9.0")]),i("li",[t._v("部署脚本运行结束时,增加信息和错误提示")]),i("li",[t._v("移除agentDependency,nmap更新到7.90")])])])])]),i("el-card",{staticClass:"box-card"},[i("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[i("span",[i("b",[t._v("正式版 V2.0 - 20200925")])]),i("div",{staticClass:"text"},[i("ol",[t._v(" 正式版发布,同时开源 ")])])])]),i("el-card",{staticClass:"box-card"},[i("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[i("span",[i("b",[t._v("公测版 V1.3.25 - 20200913")])]),i("div",{staticClass:"text"},[i("ol",[t._v(" 前端: "),i("li",[t._v("修复 子任务Drawer,调整分页无效的问题")]),i("li",[t._v("优化 用code标签显示代码")]),i("li",[t._v("新增 插件页面新增插件代码高亮,python3的selfd插件可前端新增(已知bug,第一次进入插件页面,新增或编辑需要打开两次代码高亮插件才会正常显示,第二次保存才能正常添加代码)")]),i("li",[t._v("新增 设置-批量导入,新增python3的selfd插件配置导入,主要用于python3的selfd插件配置及代码导入")]),i("li",[t._v("新增 新增各个类型任务的demo")]),t._v(" 后端: "),i("li",[t._v("修复 nse类型任务,获取状态时不显示PID信息")]),i("li",[t._v("修复 nse、selfd、httpp任务,资产库无对应的信息时,任务也会发给agent")]),i("li",[t._v("修复 无资产ip时,目标ip为ipNoPort,unknownPortSerVer,ipAllPort,任务也会发给agent")]),i("li",[t._v("修复 修复插件未设置服务和版本时,启动任务会开启所有插件 ")]),i("li",[t._v("优化 优化新增自定义插件,插件核心增加Jep方式调用python代码,可前端直接新增python3的selfd自定义类型的插件(重要更新,TDL的一半,优化新增自定义插件并丰富插件)")]),i("li",[t._v("优化 优化全部批量删除")]),i("li",[t._v("新增 新增python3的selfd插件配置导入接口")]),i("li",[t._v("新增 agent新增python插件import检测,如模块未安装,则会自动安装")]),i("li",[t._v("新增 插件配置新增http、dns辅助验证,用于插件辅助验证无回显漏洞(TDL 增加无回显插件检测)")]),i("li",[t._v("新增 增加HTTP json插件解析")]),i("li",[t._v("修改 随机获取ua的方式修改,存入redis进行随机")]),t._v(" 数据库: "),i("li",[t._v("新增 插件配置新增plugincode字段,用于保存插件代码")]),i("li",[t._v("新增 插件配置新增validatetype字段,用于开启插件http辅助验证或dns辅助验证")]),t._v(" 配置文件: "),i("li",[t._v("新增 agent.yml新增jep节点,用于保存JEP本地库的绝对路径")]),i("li",[t._v("新增 agent.yml新增center节点,用于插件辅助验证时传递http接口和dns的ip地址")]),t._v(" 部署脚本: "),i("li",[t._v("增加 新增Python3.8编译安装")]),i("li",[t._v("移除 移除jre14,修改成jdk15(JEP编译需要)")]),t._v(" 文档: "),i("li",[t._v("优化 优化快速上手及说明文档")]),i("li",[t._v("增加 新增Readme文档")]),i("li",[t._v("增加 新增插件编写说明")])])])])]),i("el-card",{staticClass:"box-card"},[i("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[i("span",[i("b",[t._v("公测版 V1.2.2 - 20200722")])]),i("div",{staticClass:"text"},[i("ol",[i("li",[t._v("优化center部署脚本,增加判断是否已经运行过部署脚本,避免误操作二次运行部署脚本(如果已经部署,则需要用户交互),优化docker服务运行状态检测")]),i("li",[t._v("优化initDataAndStart.sh,增加脚本复制和执行成功的判断")]),i("li",[t._v("修改center.yml,token过期时间设置成一小时")]),i("li",[t._v("优化任务插件显示,将插件启用状态体现到操作中,优化插件启用禁用")]),i("li",[t._v("新增子任务展开Drawer")]),i("li",[t._v("about页面版本上增加changelog的Drawer,增加更新日志及TDL")]),i("li",[t._v("前端依赖更新到最新")])])])])]),i("el-card",{staticClass:"box-card"},[i("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[i("span",[i("b",[t._v("公测版 V1.2.1 - 20200715")])]),i("div",{staticClass:"text"},[i("ol",[t._v(" 前端: "),i("li",[t._v("增加about页面")]),i("li",[t._v("增加菜单栏显示与隐藏的Collapse,涉及的页面:任务、资产ip、资产端口、主机、检测结果、web信息、web信息和url")]),i("li",[t._v("优化资产ip,去除编辑页面显示ip所有信息,修改成Drawer方式显示,并增加url超链接")]),i("li",[t._v("优化资产端口,去除编辑页面显示端口所有信息,修改成Drawer方式显示,并增加http和https链接打开,增加url超链接")]),i("li",[t._v("优化新建任务的数量前端样式,将input修改成number模式")]),i("li",[t._v("优化检测类型任务,将input修改成单选模式")]),i("li",[t._v("优化web信息中ip的显示,增加打开http和https链接的Popover")]),i("li",[t._v("首页四个折线图修改成显示最新数据的10%")]),i("li",[t._v("修改设置-通知设置中的风险等级编辑样式,从input改成单选模式")]),i("li",[t._v("修改cron表达式解析结果的样式,改成表格")])])])])]),i("el-card",{staticClass:"box-card"},[i("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[i("span",[i("b",[t._v("公测版 V1.2.0 - 20200706")])]),i("div",{staticClass:"text"},[i("ol",[t._v(" 公开公测开启 ")])])])]),i("el-card",{staticClass:"box-card"},[i("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[i("span",[i("b",[t._v("内测版 V1.1 - 20200615")])]),i("div",{staticClass:"text"},[i("ol",[i("li",[t._v("优化部署步骤,修改部署脚本成一键部署")]),i("li",[t._v("部署脚本增加系统源修改判断和docker镜像源修改判断(需要用户交互)")]),i("li",[t._v("部署脚本增加判断,提高安装部署成功率")]),i("li",[t._v("前端增加web信息功能,后端优化部分代码")]),i("li",[t._v("文档增加Q/A章节、微信公众号、项目的目录结构说明,为公测做准备")]),i("li",[t._v("增加公测宣传文档")]),i("li",[t._v("增加magicude执行脚本,便于查看系统状态及操作系统(0624)")])])])])]),i("el-card",{staticClass:"box-card"},[i("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[i("span",[i("b",[t._v("内测版 V1.0 - 20200528")])]),i("div",{staticClass:"text"},[i("ol",[t._v(" 公开内测开启 ")])])])])],1)],1)},e=[],s={data:function(){return{drawer:!1}},methods:{handleDrawer:function(){this.drawer=!0},handleDrawerClose:function(){this.drawer=!1},getYear:function(){var t=new Date;return this.year=t.getFullYear(),this.year}}},r=s,v=(i("10dd"),i("2877")),d=Object(v["a"])(r,a,e,!1,null,null,null);l["default"]=d.exports}}]); \ No newline at end of file diff --git a/deploy/MagiCude/operation/checkDockerImageStatus.sh b/deploy/MagiCude/operation/checkDockerImageStatus.sh index 303bcc8..8cc7cf8 100644 --- a/deploy/MagiCude/operation/checkDockerImageStatus.sh +++ b/deploy/MagiCude/operation/checkDockerImageStatus.sh @@ -9,7 +9,7 @@ dockerNameArrays=("nginxApp" "magicude_mysql" "magicude_redis" "magicude_rabbitm for imageName in ${dockerNameArrays[@]} ; do existFlag=`docker ps | grep $imageName |wc -L` if [ $existFlag -eq 0 ] ;then - logInfo "$imageName 未启动,正在启动 $imageName" + logWarn "$imageName 未启动,正在启动 $imageName" docker start $imageName >/dev/null 2>&1 logInfo "$imageName 完成启动" else logInfo "$imageName 已启动" diff --git a/deploy/MagiCude/operation/dockerStopService.sh b/deploy/MagiCude/operation/dockerStopService.sh index 963675f..15b53db 100644 --- a/deploy/MagiCude/operation/dockerStopService.sh +++ b/deploy/MagiCude/operation/dockerStopService.sh @@ -3,13 +3,13 @@ # https://github.com/er10yi source /root/MagiCude/util.sh -logInfo "停止docker容器" +logWarn "停止docker容器" # stop docker images dockerNameArrays=("nginxApp" "magicude_mysql" "magicude_redis" "magicude_rabbitmq") for imageName in ${dockerNameArrays[@]} ; do existFlag=`docker ps | grep $imageName |wc -L` if [ $existFlag -ne 0 ] ;then - logInfo "正在停止 $imageName" + logWarn "正在停止 $imageName" docker stop $imageName > /dev/null 2>&1 & wait fi diff --git a/deploy/MagiCude/operation/restartAll.sh b/deploy/MagiCude/operation/restartAll.sh index 31aa220..9508884 100644 --- a/deploy/MagiCude/operation/restartAll.sh +++ b/deploy/MagiCude/operation/restartAll.sh @@ -3,10 +3,10 @@ # https://github.com/er10yi source /root/MagiCude/util.sh -logInfo "$0 将执行以下操作" -logInfo "停止nmap和masscan" -logInfo "重启docker中的容器:magicude_mysql magicude_redis magicude_rabbitmq nginxApp" -logInfo "重启center所有服务:eurekaapp.jar centerapp.jar agentapp.jar" +logWarn "$0 将执行以下操作" +logWarn "停止nmap和masscan" +logWarn "重启docker中的容器:magicude_mysql magicude_redis magicude_rabbitmq nginxApp" +logWarn "重启center所有服务:eurekaapp.jar centerapp.jar agentapp.jar" echo -n "是否继续(10秒后默认N)? [y/N]: " read -t 10 checkYes if [[ $checkYes = "y" ]] ; then @@ -15,7 +15,7 @@ if [[ $checkYes = "y" ]] ; then for jarName in ${jarNameArrays[@]} ; do tempPid=`ps -ef|grep $jarName|grep -v grep|cut -c 9-15` if [ $tempPid ] ;then - logInfo "停止 $jarName" + logWarn "停止 $jarName" kill -9 $tempPid fi done @@ -23,16 +23,16 @@ if [[ $checkYes = "y" ]] ; then # kill nmap masscan existFlag=`ps -ef|grep nmap|grep -v grep|cut -c 9-15` if [ $existFlag ] ;then - logInfo "停止 nmap" + logWarn "停止 nmap" kill -9 $(pidof nmap) fi existFlag=`ps -ef|grep masscan|grep -v grep|cut -c 9-15` if [ $existFlag ] ;then - logInfo "停止 masscan" + logWarn "停止 masscan" kill -9 $(pidof masscan) fi logInfo "完成" - logInfo "docker重启容器" + logWarn "docker重启容器" docker restart magicude_mysql > /dev/null 2>&1 & docker restart magicude_redis > /dev/null 2>&1 & docker restart magicude_rabbitmq > /dev/null 2>&1 & diff --git a/deploy/MagiCude/operation/stopAll.sh b/deploy/MagiCude/operation/stopAll.sh index 742a704..572e8f4 100644 --- a/deploy/MagiCude/operation/stopAll.sh +++ b/deploy/MagiCude/operation/stopAll.sh @@ -3,40 +3,40 @@ # https://github.com/er10yi source /root/MagiCude/util.sh -logInfo "$0 将执行以下操作" -logInfo "停止nmap和masscan" -logInfo "停止docker中的容器:magicude_mysql magicude_redis magicude_rabbitmqnginxApp" -logInfo "停止center所有服务:eurekaapp.jar centerapp.jar agentapp.jar" -logInfo "如果部署了多个agent,请到agent服务器手动执行 stopAgent.sh" +logWarn "$0 将执行以下操作" +logWarn "停止nmap和masscan" +logWarn "停止docker中的容器:magicude_mysql magicude_redis magicude_rabbitmqnginxApp" +logWarn "停止center所有服务:eurekaapp.jar centerapp.jar agentapp.jar" +logWarn "如果部署了多个agent,请到agent服务器手动执行 stopAgent.sh" echo -n "是否继续(10秒后默认N)? [y/N]: " read -t 10 checkYes if [[ $checkYes = "y" ]] ; then - logInfo "停止 MagiCude 所有服务" + logWarn "停止 MagiCude 所有服务" # kill jar jarNameArrays=("eurekaapp" "centerapp" "agentapp") for jarName in ${jarNameArrays[@]} ; do tempPid=`ps -ef|grep $jarName|grep -v grep|cut -c 9-15` if [ $tempPid ] ;then - logInfo "停止 $jarName" + logWarn "停止 $jarName" kill -9 $tempPid fi done logInfo "完成" - logInfo "停止 nmap和masscan" + logWarn "停止 nmap和masscan" # kill nmap masscan existFlag=`ps -ef|grep nmap|grep -v grep|cut -c 9-15` if [ $existFlag ] ;then - logInfo "停止 nmap" + logWarn "停止 nmap" kill -9 $(pidof nmap) fi existFlag=`ps -ef|grep masscan|grep -v grep|cut -c 9-15` if [ $existFlag ] ;then - logInfo "停止 masscan" + logWarn "停止 masscan" kill -9 $(pidof masscan) fi logInfo "完成" - logInfo "docker停止容器" + logWarn "docker停止容器" docker stop magicude_mysql > /dev/null 2>&1 & docker stop magicude_redis > /dev/null 2>&1 & docker stop magicude_rabbitmq > /dev/null 2>&1 & diff --git a/deploy/MagiCude/operation/stopCenterService.sh b/deploy/MagiCude/operation/stopCenterService.sh index 7d0c3b3..198beca 100644 --- a/deploy/MagiCude/operation/stopCenterService.sh +++ b/deploy/MagiCude/operation/stopCenterService.sh @@ -3,12 +3,12 @@ # https://github.com/er10yi source /root/MagiCude/util.sh -logInfo "停止 MagiCude 服务" +logWarn "停止 MagiCude 服务" jarNameArrays=("eurekaapp" "centerapp" "agentapp") for jarName in ${jarNameArrays[@]} ; do tempPid=`ps -ef|grep $jarName|grep -v grep|cut -c 9-15` if [ $tempPid ] ;then - logInfo "停止 $jarName" + logWarn "停止 $jarName" kill -9 $tempPid fi done diff --git a/deploy/defaultConf/agent.yml b/deploy/defaultConf/agent.yml index f706f78..6413f5c 100644 --- a/deploy/defaultConf/agent.yml +++ b/deploy/defaultConf/agent.yml @@ -22,7 +22,7 @@ eureka: register-with-eureka: true fetch-registry: true service-url: - defaultZone: http://${eureka.user.name}:${eureka.user.password}@127.0.0.1:8686/eureka # 127.0.0.1需要改成部署eurekaapp.jar服务器的ip + defaultZone: http://${eureka.user.name}:${eureka.user.password}@127.0.0.1:8686/eureka # 需要改成部署eurekaapp.jar服务器的ip instance: prefer-ip-address: true nmap: diff --git a/deploy/defaultConf/initAgentEnvironmentAndStart.sh b/deploy/defaultConf/initAgentEnvironmentAndStart.sh index 375b12c..6c90ddd 100644 --- a/deploy/defaultConf/initAgentEnvironmentAndStart.sh +++ b/deploy/defaultConf/initAgentEnvironmentAndStart.sh @@ -5,7 +5,7 @@ source /root/MagiCude/util.sh echo -echo "魔方-MagiCude agent部署脚本 V2.5" +echo "魔方-MagiCude agent部署脚本 V2.6" echo "@author 贰拾壹" echo "https://github.com/er10yi" echo @@ -42,7 +42,7 @@ fi # 如果$openjdkDirName已解压,证明已经运行过部署脚本 if [ -d $openjdkDirName ]; then - logInfo "检测到已运行过部署脚本" + logWarn "检测到已运行过部署脚本" echo -n "是否继续(10秒后默认N)? [y/N]: " read -t 10 checkYes if [[ $checkYes != "y" ]] ; then @@ -67,10 +67,60 @@ if [ $existFlag ] ;then kill -9 $(pidof masscan) fi +function check_ip() { + local agentRealIp=$1 + VALID_CHECK=$( echo $agentRealIp| awk -F. '$1<=255&&$2<=255&&$3<=255&&$4<=255{print "yes"}' ) + if echo $agentRealIp| grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" > /dev/null ; then + if [[ $VALID_CHECK = "yes" ]]; then + logInfo "正在ping $agentRealIp" + check_ret=`ping ${agentRealIp} -c 2 | grep -q 'ttl=' && echo "yes" || echo "no"` + if [ $check_ret = "no" ];then + logErrorNotExit "$agentRealIp 无法ping通" + return 1 + else + logInfo "替换agent.yml中的127.0.0.1" + sed -i "s/127.0.0.1/$agentRealIp/g" agent.yml + return 0 + fi + else + logErrorNotExit "$agentRealIp 无效的IP" + return 1 + fi + else + logErrorNotExit "$agentRealIp 格式错误" + return 1 + fi +} + # 判断agent.yml内容是否已经修改 # agent分布式部署 if [ ! -f initCenterEnvironmentAndStart.sh ]; then + # 修改agent.yml logInfo "检测到agent分布式部署" + # 需要手动输入服务器的ip地址 + existFlag=`cat agent.yml | grep "name: agent1" |wc -L` + if [ $existFlag -ne 0 ] ;then + logInfo "修改agent.yml中的name: agent1" + logWarn "要求:不能是agent1, 需唯一且只能英文且不能包含空格" + echo -n "请输入agent的名字: " + read newName + logInfo "替换agent.yml中的name: agent1" + sed -i "s/name: agent1/name: $newName/g" agent.yml + fi + + logInfo "修改agent.yml中center相关的ip" + existFlag=`cat agent.yml | grep "127.0.0.1" |wc -L` + if [ $existFlag -ne 0 ] ;then + while true ; do + echo -n "请输入部署center的服务IP地址: " + read agentRealIp + check_ip "${agentRealIp}" + if [ $? -eq 0 ]; then + break + fi + done + fi + existFlag=`cat agent.yml | grep "name: agent1" |wc -L` if [ $existFlag -ne 0 ] ;then logError "agent.yml文件name节点 agent1 未修改,请修改成非 agent1 后重新运行 $0" @@ -97,12 +147,10 @@ if [ -f agent.yml ];then if [ $existFlag -ne 0 ] ;then infoMessage+=("agent.yml文件center节点dnsValidateIp未修改:请将dnsValidateIp修改成部署centerapp.jar服务器的ip") fi -else - logError "agent.yml不存在" fi logInfo "判断是否存在java 环境" -java -version >/dev/null 2>&1 +type java >/dev/null 2>&1 if [ $? -eq 0 ];then # 存在java环境 java_version=`java -version 2>&1 | sed '1!d' | sed -e 's/"//g' | awk '{print $3}'` @@ -132,8 +180,8 @@ yum -y install gcc make libpcap libpcap-dev clang git wget >/dev/null 2>&1 logInfo "验证依赖是否成功安装" dependArrays=("wget" "make" "gcc" "clang" "git") for dependName in ${dependArrays[@]} ; do - existFlag=`ls /usr/bin/ | grep $dependName |wc -L` - if [ $existFlag -eq 0 ] ;then + type $dependName >/dev/null 2>&1 + if [ $? -ne 0 ];then logError "$dependName未成功安装,请重新执行 $0" fi done @@ -144,7 +192,7 @@ pythonVerion=${pythonVersionArrays[0]} # i=1 # while ( [ $i -le ${#pythonVersionArrays[*]} ] ) # do -# echo "$i.Python ${pythonVersionArrays[i-1]}" +# echo "$i Python ${pythonVersionArrays[i-1]}" # let "i++" # done # echo -n "10秒后默认选第 1 项 : " @@ -178,7 +226,7 @@ if [ ! -f $pythonNameVerion$pythonTarName ]; then logError "$pythonNameVerion下载失败,重试第$i次失败,请重新执行 $0" fi fi -python3 --version >/dev/null 2>&1 +type python3 >/dev/null 2>&1 if [ $? -ne 0 ];then tar -xJf $pythonNameVerion$pythonTarName mkdir /usr/local/python3 >/dev/null 2>&1 @@ -191,9 +239,9 @@ if [ $? -ne 0 ];then cd .. rm -rf $pythonNameVerion >/dev/null 2>&1 fi -logInfo "判断 $pythonNameVerion 是否成功安装" -python3 --version >/dev/null 2>&1 -if [ $? != 0 ];then +logInfo "判断$pythonNameVerion是否成功安装" +type python3 >/dev/null 2>&1 +if [ $? -ne 0 ];then logError "$pythonNameVerion 未成功安装,请重新执行 $0" fi logInfo "替换agent.yml中的jep.absolutePath的python路径" @@ -248,13 +296,12 @@ pip3 install wheel -i https://pypi.douban.com/simple/ >/dev/null 2>&1 pip3 install jep -i https://pypi.douban.com/simple/ >/dev/null 2>&1 logInfo "安装nmap和masscan" -existFlag=`ls /usr/bin/ | grep nmap |wc -L` -if [ $existFlag -eq 0 ] ;then +type nmap >/dev/null 2>&1 +if [ $? -ne 0 ];then rpm -U $nmapUrl >/dev/null 2>&1 fi - -existFlag=`ls /usr/bin/ | grep masscan |wc -L` -if [ $existFlag -eq 0 ] ;then +type masscan >/dev/null 2>&1 +if [ $? -ne 0 ];then if [ ! -d masscan ]; then i=0 while ( [ $i -lt 5 ] ) @@ -279,8 +326,8 @@ fi logInfo "验证nmap masscan是否成功安装" dependArrays=("masscan" "nmap") for dependName in ${dependArrays[@]} ; do - existFlag=`ls /usr/bin/ | grep $dependName |wc -L` - if [ $existFlag -eq 0 ] ;then + type $dependName >/dev/null 2>&1 + if [ $? -ne 0 ];then logError "$dependName未成功安装,请重新执行 $0" fi done @@ -291,10 +338,10 @@ sh runAgent.sh if [ ${#infoMessage[*]} -ne 0 ];then echo - echo "以下信息不会影响魔方正常运行,但可能会导致agent部分功能不可用,请根据提示进行修改,并重启agent" - logInfo "info start" + logWarn "以下信息不会影响魔方正常运行,但可能会导致agent部分功能不可用,请根据提示进行修改,并重启agent" + logWarn "info start" for info in ${infoMessage[@]} ; do echo -e "$info" done - logInfo "info end" + logWarn "info end" fi \ No newline at end of file diff --git a/deploy/defaultConf/initCenterEnvironmentAndStart.sh b/deploy/defaultConf/initCenterEnvironmentAndStart.sh index 0bc3dd3..e4a0b36 100644 --- a/deploy/defaultConf/initCenterEnvironmentAndStart.sh +++ b/deploy/defaultConf/initCenterEnvironmentAndStart.sh @@ -5,7 +5,7 @@ source /root/MagiCude/util.sh echo -echo "魔方-MagiCude 一键部署脚本 V2.5" +echo "魔方-MagiCude 一键部署脚本 V2.6" echo "@author 贰拾壹" echo "https://github.com/er10yi" echo @@ -44,9 +44,9 @@ fi # 如果$openjdkDirName已解压,证明已经运行过部署脚本 if [ -d $openjdkDirName ]; then - logInfo "检测到已运行过部署脚本" - logInfo "继续运行脚本将重置数据库,当前数据会丢失" - logInfo "如已正常部署,请勿执行" + logWarn "检测到已运行过部署脚本" + logWarn "继续运行脚本将重置数据库,当前数据会丢失" + logWarn "如已正常部署,请勿执行" echo -n "是否继续(10秒后默认N)? [y/N]: " read -t 10 checkYes if [[ $checkYes != "y" ]] ; then @@ -74,8 +74,8 @@ if [ $existFlag ] ;then kill -9 $(pidof masscan) fi # stop and remove docker images -existFlag=`ls /usr/bin/ | grep docker |wc -L` -if [ $existFlag -ne 0 ] ;then +type docker >/dev/null 2>&1 +if [ $? -eq 0 ] ;then dockerNameArrays=("nginxApp" "magicude_mysql" "magicude_redis" "magicude_rabbitmq") systemctl restart docker for imageName in ${dockerNameArrays[@]} ; do @@ -88,6 +88,38 @@ if [ $existFlag -ne 0 ] ;then systemctl stop docker fi +# 修改前端api地址及agent.yml +errorMessage=() +existFlag=`cat dist/static/js/app.*.js | grep "http://127.0.0.1:9001" |wc -L` +if [ $existFlag -ne 0 ] ;then + tempIp=`ip a |grep -w inet|awk '{print $2}'|awk -F '/' '{print $1}'` + ipArray=(${tempIp// / }) + logInfo "服务器所有IP如下: " + i=1 + while ( [ $i -le ${#ipArray[*]} ] ) + do + echo "$i ${ipArray[i-1]}" + let "i++" + done + echo -n "请输入数字选择部署center的IP地址: " + read choice + if [ ! $choice ]; then + logErrorNotExit "未选择有效的IP地址" + logError "请重新执行 $0" + fi + if [[ $choice -gt ${#ipArray[*]} ]] || [[ $choice -lt 1 ]]; then + logErrorNotExit "未选择有效的IP地址" + logError "请重新执行 $0" + fi + let "choice--" + centerRealIp="${ipArray[choice]}" + logInfo "替换前端api地址" + sed -i "s/127.0.0.1/$centerRealIp/g" dist/static/js/app.*.js + logInfo "替换agent.yml中的地址" + sed -i "s/httpValidateApi: http:\/\/127.0.0.1/httpValidateApi: http:\/\/$centerRealIp/g" agent.yml + sed -i "s/dnsValidateIp: 127.0.0.1/dnsValidateIp: $centerRealIp/g" agent.yml +fi + # 判断前端api地址是否修改 errorMessage=() existFlag=`cat dist/static/js/app.*.js | grep "http://127.0.0.1:9001" |wc -L` @@ -110,7 +142,7 @@ else fi logInfo "判断是否存在java环境" -java -version >/dev/null 2>&1 +type java >/dev/null 2>&1 if [ $? -eq 0 ];then # 存在java环境 java_version=`java -version 2>&1 | sed '1!d' | sed -e 's/"//g' | awk '{print $3}'` @@ -141,8 +173,8 @@ yum -y install wget fontconfig stix-fonts ntpdate docker gcc make libpcap libpca logInfo "验证依赖是否成功安装" dependArrays=("wget" "docker" "make" "gcc" "clang" "git") for dependName in ${dependArrays[@]} ; do - existFlag=`ls /usr/bin/ | grep $dependName |wc -L` - if [ $existFlag -eq 0 ] ;then + type $dependName >/dev/null 2>&1 + if [ $? -ne 0 ];then logError "$dependName 未成功安装,请重新执行 $0" fi done @@ -153,7 +185,7 @@ pythonVerion=${pythonVersionArrays[0]} # i=1 # while ( [ $i -le ${#pythonVersionArrays[*]} ] ) # do -# echo "$i.Python ${pythonVersionArrays[i-1]}" +# echo "$i Python ${pythonVersionArrays[i-1]}" # let "i++" # done # echo -n "10秒后默认选第 1 项 : " @@ -188,7 +220,7 @@ if [ ! -f $pythonNameVerion$pythonTarName ]; then logError "$pythonNameVerion下载失败,重试第$i次失败,请重新执行 $0" fi fi -python3 --version >/dev/null 2>&1 +type python3 >/dev/null 2>&1 if [ $? -ne 0 ];then tar -xJf $pythonNameVerion$pythonTarName mkdir /usr/local/python3 >/dev/null 2>&1 @@ -201,8 +233,8 @@ if [ $? -ne 0 ];then cd .. rm -rf $pythonNameVerion fi -logInfo "判断 $pythonNameVerion 是否成功安装" -python3 --version >/dev/null 2>&1 +logInfo "判断$pythonNameVerion是否成功安装" +type python3 >/dev/null 2>&1 if [ $? -ne 0 ];then logError "$pythonNameVerion 未成功安装,请重新执行 $0" fi @@ -263,12 +295,12 @@ pip3 install wheel -i https://pypi.douban.com/simple/ >/dev/null 2>&1 pip3 install jep -i https://pypi.douban.com/simple/ >/dev/null 2>&1 logInfo "安装nmap和masscan" -existFlag=`ls /usr/bin/ | grep nmap |wc -L` -if [ $existFlag -eq 0 ] ;then +type nmap >/dev/null 2>&1 +if [ $? -ne 0 ];then rpm -U $nmapUrl >/dev/null 2>&1 fi -existFlag=`ls /usr/bin/ | grep masscan |wc -L` -if [ $existFlag -eq 0 ] ;then +type masscan >/dev/null 2>&1 +if [ $? -ne 0 ];then if [ ! -d masscan ]; then i=0 while ( [ $i -lt 5 ] ) @@ -290,12 +322,12 @@ if [ $existFlag -eq 0 ] ;then rm -rf masscan >/dev/null 2>&1 fi -logInfo "验证docker nmap masscan是否成功安装" -dependArrays=("docker" "masscan" "nmap") +logInfo "验证nmap masscan是否成功安装" +dependArrays=("masscan" "nmap") for dependName in ${dependArrays[@]} ; do - existFlag=`ls /usr/bin/ | grep $dependName |wc -L` - if [ $existFlag -eq 0 ] ;then - logError "$dependName 未成功安装,请重新执行 $0" + type $dependName >/dev/null 2>&1 + if [ $? -ne 0 ];then + logError "$dependName未成功安装,请重新执行 $0" fi done @@ -340,7 +372,7 @@ do if [ $imageName = "rabbitmq" ]; then imageName="rabbitmq:management" fi - logInfo "$imageName 不存在,正在重新pull $imageName" + logWarn "$imageName 不存在,正在重新pull $imageName" docker pull $imageName >/dev/null 2>&1 & wait if [ $imageName = "rabbitmq" ]; then @@ -377,7 +409,7 @@ logInfo "确保容器服务已成功运行" i=1 while ( [ -z "`docker exec -it magicude_mysql /bin/bash -c "mysql -uroot -p8TAQRc9EOkV607qm -e'show databases'" | grep "information_schema"`" ] && [ $i -lt 6 ] ) do - logInfo "magicude_mysql未启动,第$i次重启" + logWarn "magicude_mysql未启动,第$i次重启" docker start magicude_mysql >/dev/null 2>&1 let "i++" sleep 10s @@ -394,7 +426,7 @@ for imageName in ${dockerNameArrays[@]} ; do i=1 while ( [ -z "`docker exec -it $imageName /bin/bash -c "ls /" | grep "root"`" ] && [ $i -lt 6 ] ) do - logInfo "$imageName未启动,第$i次重启" + logWarn "$imageName未启动,第$i次重启" docker start $imageName >/dev/null 2>&1 let "i++" sleep 10s @@ -417,19 +449,19 @@ sh initDataAndStart.sh if [ ${#infoMessage[*]} -ne 0 ];then echo - echo "以下信息不会影响魔方正常运行,但可能会导致部分功能不可用,请根据提示进行修改,并重启魔方" - logInfo "info start" + logWarn "以下信息不会影响魔方正常运行,但可能会导致部分功能不可用,请根据提示进行修改,并重启魔方" + logWarn "info start" for info in ${infoMessage[@]} ; do echo -e "$info" done - logInfo "info end" + logWarn "info end" fi if [ ${#errorMessage[*]} -ne 0 ];then echo - echo "以下错误会影响魔方正常运行,导致魔方不可用,请根据提示进行修改,并重启魔方" - logInfo "error start" + logErrorNotExit "以下错误会影响魔方正常运行,导致魔方不可用,请根据提示进行修改,并重启魔方" + logErrorNotExit "error start" for error in ${errorMessage[@]} ; do echo -e "$error" done - logInfo "error end" + logErrorNotExit "error end" fi diff --git a/deploy/defaultConf/magicude b/deploy/defaultConf/magicude index 360f1e9..fa1d01f 100644 --- a/deploy/defaultConf/magicude +++ b/deploy/defaultConf/magicude @@ -36,7 +36,7 @@ dockerStatusAndStart() for imageName in ${dockerNameArrays[@]} ; do existFlag=`docker ps | grep $imageName |wc -L` if [ $existFlag -eq 0 ] ;then - logInfo "$imageName 未启动, 正在启动 $imageName" + logWarn "$imageName 未启动, 正在启动 $imageName" docker start $imageName >/dev/null 2>&1 logInfo "$imageName 启动完成" else logInfo "$imageName 已启动" @@ -52,7 +52,7 @@ statusAndStart() for jarName in ${jarNameArrays[@]} ; do existFlag=`ps -ef|grep $jarName|grep -v grep|wc -L` if [ $existFlag -eq 0 ] ;then - logInfo "$jarName 未启动,正在启动 $jarName" + logWarn "$jarName 未启动,正在启动 $jarName" temp=$jarName nohup java -jar "$jarName.jar" --spring.config.location="${temp/app/}".yml > /dev/null 2>&1 & logInfo "$jarName 启动完成" @@ -79,7 +79,7 @@ start() stop() { - logInfo "停止 MagiCude 所有服务" + logWarn "停止 MagiCude 所有服务" jarNameArrays=("eurekaapp" "centerapp" "agentapp") for jarName in ${jarNameArrays[@]} ; do tempPid=`ps -ef|grep $jarName|grep -v grep|cut -c 9-15` @@ -88,7 +88,7 @@ stop() fi done logInfo "完成" - logInfo "停止 nmap和masscan" + logWarn "停止 nmap和masscan" existFlag=`ps -ef|grep nmap|grep -v grep|cut -c 9-15` if [ $existFlag ] ;then kill -9 $(pidof nmap) @@ -98,7 +98,7 @@ stop() kill -9 $(pidof masscan) fi logInfo "完成" - logInfo "停止 docker 容器" + logWarn "停止 docker 容器" dockerNameArrays=("nginxApp" "magicude_mysql" "magicude_redis" "magicude_rabbitmq") for imageName in ${dockerNameArrays[@]} ; do existFlag=`docker ps | grep $imageName |wc -L` diff --git a/deploy/defaultConf/magicude.sql b/deploy/defaultConf/magicude.sql index ef56068..e08143d 100644 --- a/deploy/defaultConf/magicude.sql +++ b/deploy/defaultConf/magicude.sql @@ -976,9 +976,6 @@ CREATE TABLE `tb_taskip` ( -- ---------------------------- -- Records of tb_taskip -- ---------------------------- -INSERT INTO `tb_taskip` VALUES ('1314483884750147584', '1304326543249641472', '127.0.0.1', NULL, 0); -INSERT INTO `tb_taskip` VALUES ('1314485012380389376', '1304327021228331008', '127.0.0.1', NULL, 0); -INSERT INTO `tb_taskip` VALUES ('1314485455953203200', '1314485452954275840', '127.0.0.1', NULL, 0); -- ---------------------------- -- Table structure for tb_taskpluginconfig @@ -1016,56 +1013,6 @@ CREATE TABLE `tb_taskport` ( -- ---------------------------- -- Records of tb_taskport -- ---------------------------- -INSERT INTO `tb_taskport` VALUES ('1314483885274435584', '1314483884750147584', '3306', 'tcp', 'open', 'mysql', 'MySQL 8.0.21', 0); -INSERT INTO `tb_taskport` VALUES ('1314483909760782336', '1314483884750147584', '22', 'tcp', 'open', 'ssh', 'OpenSSH 7.4 (protocol 2.0)', 0); -INSERT INTO `tb_taskport` VALUES ('1314483909790142464', '1314483884750147584', '25', 'tcp', 'open', 'smtp', 'Postfix smtpd', 0); -INSERT INTO `tb_taskport` VALUES ('1314483909827891200', '1314483884750147584', '80', 'tcp', 'open', 'http', 'nginx 1.19.3', 0); -INSERT INTO `tb_taskport` VALUES ('1314483911727910912', '1314483884750147584', '4369', 'tcp', 'open', 'epmd', 'Erlang Port Mapper Daemon', 0); -INSERT INTO `tb_taskport` VALUES ('1314483928450600960', '1314483884750147584', '5672', 'tcp', 'open', 'amqp', 'RabbitMQ 3.8.9 (0-9)', 0); -INSERT INTO `tb_taskport` VALUES ('1314483928479961088', '1314483884750147584', '5671', 'tcp', 'open', 'tcpwrapped', 'null', 0); -INSERT INTO `tb_taskport` VALUES ('1314483953985523712', '1314483884750147584', '6379', 'tcp', 'open', 'redis', 'Redis key-value store', 0); -INSERT INTO `tb_taskport` VALUES ('1314483960394420224', '1314483884750147584', '8686', 'tcp', 'open', 'sun-as-jmxrmi?', 'null', 0); -INSERT INTO `tb_taskport` VALUES ('1314483960914513920', '1314483884750147584', '9001', 'tcp', 'open', 'tor-orport?', 'null', 0); -INSERT INTO `tb_taskport` VALUES ('1314483961065508864', '1314483884750147584', '9991', 'tcp', 'open', 'issa?', 'null', 0); -INSERT INTO `tb_taskport` VALUES ('1314483979763716096', '1314483884750147584', '15672', 'tcp', 'open', 'http', 'Cowboy httpd', 0); -INSERT INTO `tb_taskport` VALUES ('1314483979839213568', '1314483884750147584', '15671', 'tcp', 'open', 'tcpwrapped', 'null', 0); -INSERT INTO `tb_taskport` VALUES ('1314485012434915328', '1314485012380389376', '913', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012451692544', '1314485012380389376', '903', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012468469760', '1314485012380389376', '49667', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012522995712', '1314485012380389376', '808', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012548161536', '1314485012380389376', '10001', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012569133056', '1314485012380389376', '445', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012590104576', '1314485012380389376', '443', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012615270400', '1314485012380389376', '49669', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012632047616', '1314485012380389376', '49665', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012648824832', '1314485012380389376', '49670', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012669796352', '1314485012380389376', '4000', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012682379264', '1314485012380389376', '135', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012703350784', '1314485012380389376', '5040', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012724322304', '1314485012380389376', '49664', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012745293824', '1314485012380389376', '7680', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012774653952', '1314485012380389376', '28317', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012795625472', '1314485012380389376', '2968', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012816596992', '1314485012380389376', '10000', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012833374208', '1314485012380389376', '49666', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012850151424', '1314485012380389376', '54530', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012866928640', '1314485012380389376', '49668', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012883705856', '1314485012380389376', '1362', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485012900483072', '1314485012380389376', '8307', 'tcp', 'open', NULL, NULL, 0); -INSERT INTO `tb_taskport` VALUES ('1314485456074838016', '1314485455953203200', '3306', 'tcp', 'open', 'mysql', 'MySQL 8.0.21', 0); -INSERT INTO `tb_taskport` VALUES ('1314485480770899968', '1314485455953203200', '22', 'tcp', 'open', 'ssh', 'OpenSSH 7.4 (protocol 2.0)', 0); -INSERT INTO `tb_taskport` VALUES ('1314485480796065792', '1314485455953203200', '25', 'tcp', 'open', 'smtp', 'Postfix smtpd', 0); -INSERT INTO `tb_taskport` VALUES ('1314485480821231616', '1314485455953203200', '80', 'tcp', 'open', 'http', 'nginx 1.19.3', 0); -INSERT INTO `tb_taskport` VALUES ('1314485482398289920', '1314485455953203200', '4369', 'tcp', 'open', 'epmd', 'Erlang Port Mapper Daemon', 0); -INSERT INTO `tb_taskport` VALUES ('1314485499087425536', '1314485455953203200', '5672', 'tcp', 'open', 'amqp', 'RabbitMQ 3.8.9 (0-9)', 0); -INSERT INTO `tb_taskport` VALUES ('1314485499112591360', '1314485455953203200', '5671', 'tcp', 'open', 'tcpwrapped', 'null', 0); -INSERT INTO `tb_taskport` VALUES ('1314485525029195776', '1314485455953203200', '6379', 'tcp', 'open', 'redis', 'Redis key-value store', 0); -INSERT INTO `tb_taskport` VALUES ('1314485530448236544', '1314485455953203200', '8686', 'tcp', 'open', 'sun-as-jmxrmi?', 'null', 0); -INSERT INTO `tb_taskport` VALUES ('1314485530842501120', '1314485455953203200', '9001', 'tcp', 'open', 'tor-orport?', 'null', 0); -INSERT INTO `tb_taskport` VALUES ('1314485530892832768', '1314485455953203200', '9991', 'tcp', 'open', 'issa?', 'null', 0); -INSERT INTO `tb_taskport` VALUES ('1314485549981110272', '1314485455953203200', '15672', 'tcp', 'open', 'http', 'Cowboy httpd', 0); -INSERT INTO `tb_taskport` VALUES ('1314485550006276096', '1314485455953203200', '15671', 'tcp', 'open', 'tcpwrapped', 'null', 0); -INSERT INTO `tb_taskport` VALUES ('1314486096687665152', '1314485455953203200', '25672', 'tcp', 'open', 'unknown', 'null', 0); -- ---------------------------- -- Table structure for tb_titlewhitelist diff --git a/deploy/defaultConf/stopAgent.sh b/deploy/defaultConf/stopAgent.sh index 9552c8d..c85659e 100644 --- a/deploy/defaultConf/stopAgent.sh +++ b/deploy/defaultConf/stopAgent.sh @@ -4,7 +4,7 @@ # https://github.com/er10yi source /root/MagiCude/util.sh -logInfo "停止agentapp.jar" +logWarn "停止agentapp.jar" # kill agentapp tempPid=`ps -ef|grep agentapp|grep -v grep|cut -c 9-15` if [ $tempPid ] ;then diff --git a/deploy/defaultConf/uninstall.sh b/deploy/defaultConf/uninstall.sh new file mode 100644 index 0000000..759a938 --- /dev/null +++ b/deploy/defaultConf/uninstall.sh @@ -0,0 +1,105 @@ +#!/bin/bash +# 魔方-MagiCude卸载脚本 +# @author 贰拾壹 +# https://github.com/er10yi +source /root/MagiCude/util.sh + +logInfo "$0将执行以下操作" +logWarn "1.停止魔方-MagiCude所有服务" +logWarn "2.停止nmap和masscan" +logWarn "3.停止并删除docker容器" +logWarn "4.还原系统源" +logWarn "5.移除依赖" +logWarn "6.移除nmap和masscan" +logWarn "7.移除Python3" +logWarn "8.恢复环境变量" +logWarn "9.删除/root/MagiCude" +logErrorNotExit "如果部署了多个agent,请到agent服务器手动执行 $0" +logErrorNotExit "魔方-MagiCude所有数据将丢失" +echo -n "是否继续(10秒后默认N)? [y/N]: " +read -t 10 checkYes +if [[ $checkYes != "y" ]] ; then + echo + logInfo "退出卸载" + exit 1 +fi + +logWarn "停止MagiCude所有服务" +jarNameArrays=("eurekaapp" "centerapp" "agentapp") +for jarName in ${jarNameArrays[@]} ; do + tempPid=`ps -ef|grep $jarName|grep -v grep|cut -c 9-15` + if [ $tempPid ] ;then + kill -9 $tempPid + fi +done +logWarn "停止nmap和masscan" +existFlag=`ps -ef|grep nmap|grep -v grep|cut -c 9-15` +if [ $existFlag ] ;then + kill -9 $(pidof nmap) +fi +existFlag=`ps -ef|grep masscan|grep -v grep|cut -c 9-15` +if [ $existFlag ] ;then + kill -9 $(pidof masscan) +fi +logWarn "停止并删除docker容器" +type docker >/dev/null 2>&1 +if [ $? -eq 0 ] ;then + dockerNameArrays=("nginxApp" "magicude_mysql" "magicude_redis" "magicude_rabbitmq") + systemctl restart docker + for imageName in ${dockerNameArrays[@]} ; do + existFlag=`docker ps -a | grep $imageName |wc -L` + if [ $existFlag -ne 0 ] ;then + docker stop $imageName >/dev/null 2>&1 + docker rm $imageName >/dev/null 2>&1 + fi + done + systemctl stop docker +fi + +# 还原系统源 +existFlag=`cat /etc/yum.repos.d/CentOS-Base.repo | grep ustc |wc -L` +if [ $existFlag -ne 0 ] ;then + logWarn "还原系统源" + # rm -rf /etc/yum.repos.d/CentOS-Base.repo + mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup.uninstall + mv /etc/yum.repos.d/CentOS-Base.repo.backup /etc/yum.repos.d/CentOS-Base.repo + yum clean all >/dev/null 2>&1 + yum makecache >/dev/null 2>&1 +fi + +logWarn "移除依赖" +yum -y remove wget fontconfig stix-fonts ntpdate gcc make libpcap libpcap-dev clang git >/dev/null 2>&1 +yum -y remove zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel zlib1g-dev zlib* >/dev/null 2>&1 +# docker +yum -y remove docker* >/dev/null 2>&1 +rm -rf /etc/docker >/dev/null 2>&1 +rm -rf /run/docker >/dev/null 2>&1 +rm -rf /var/lib/dockershim >/dev/null 2>&1 +rm -rf /var/lib/docker >/dev/null 2>&1 + +logWarn "移除nmap和masscan" +yum -y remove nmap >/dev/null 2>&1 +rm -rf /usr/bin/masscan >/dev/null 2>&1 + +logWarn "移除Python3" +rm -rf /usr/local/python3 >/dev/null 2>&1 +rm -rf /usr/local/bin/python3 >/dev/null 2>&1 +rm -rf /usr/local/bin/pip3 >/dev/null 2>&1 + +logWarn "恢复环境变量" +sed -i "/export JAVA_HOME=\/root\/MagiCude\/$openjdkDirName/d" /root/.bash_profile +sed -i "/export JRE_HOME=\$JAVA_HOME\/jre/d" /root/.bash_profile +sed -i "/export CLASSPATH=\$JAVA_HOME\/lib:\$JRE_HOME\/lib:\$CLASSPATH/d" /root/.bash_profile +sed -i "/export PATH=\$JAVA_HOME\/bin:\$JRE_HOME\/bin:\$PATH/d" /root/.bash_profile +sed -i "/export LD_LIBRARY_PATH=\/usr\/local\/python3\/lib/d" /root/.bash_profile +source /root/.bash_profile + +echo -n "是否删除/root/MagiCude(10秒后默认N)? [y/N]: " +read -t 10 checkYes +if [[ $checkYes == "y" ]] ; then + rm -rf /root/MagiCude +else + echo + logInfo "/root/MagiCude未删除,可重新登录远程连接后再次部署" + logInfo "如不再使用,可手动删除" +fi \ No newline at end of file diff --git a/deploy/defaultConf/util.sh b/deploy/defaultConf/util.sh index 589ba27..947ad77 100644 --- a/deploy/defaultConf/util.sh +++ b/deploy/defaultConf/util.sh @@ -19,11 +19,15 @@ function logInfo(){ echo -e "*****info*****\t $1" } +function logWarn(){ + echo -e "\033[33m*****warn*****\t $1\033[0m" +} + function logError(){ - echo -e "!!!!!error!!!!!\t $1" + echo -e "\033[31m!!!!!error!!!!!\t $1\033[0m" exit 1 } function logErrorNotExit(){ - echo -e "!!!!!error!!!!!\t $1" + echo -e "\033[31m!!!!!error!!!!!\t $1\033[0m" } \ No newline at end of file diff --git "a/\344\275\277\347\224\250\350\257\264\346\230\216.md" "b/\344\275\277\347\224\250\350\257\264\346\230\216.md" index 97e5505..2a9b219 100755 --- "a/\344\275\277\347\224\250\350\257\264\346\230\216.md" +++ "b/\344\275\277\347\224\250\350\257\264\346\230\216.md" @@ -83,6 +83,8 @@ deploy │ magicude.sql # 用于初始化数据库,下同 │ runAgent.sh # 用于启动agent,下同 │ stopAgent.sh # 用于停止agent,下同 +│ util.sh # 包含环境变量,Python版本,java版本,日志打印 +│ uninstall.sh # 卸载脚本 │ └─MagiCude # 部署需要的目录,包含初始化后的启动脚本和数据库文件,未说明的如上 │ agent.yml ****执行GenPass.jar后生成**** @@ -99,6 +101,8 @@ deploy │ runAgent.sh ****执行GenPass.jar后生成**** │ stopAgent.sh ****执行GenPass.jar后生成**** │ magicude ****执行GenPass.jar后生成**** + │ util.sh ****执行GenPass.jar后生成**** + │ uninstall.sh ****执行GenPass.jar后生成**** ├─agent # agentapp.jar 启动后才会产生 │ └─logs # agent的日志文件,如果启动失败,可查看error的日志 ├─center # centerapp.jar 启动后才会产生 @@ -107,10 +111,6 @@ deploy │ ├─asset # 资产报告,系统启动后,发送资产报告之后才会产生 │ └─vuln # 漏洞报告,系统启动后,发送漏洞报告之后才会产生 │ - ├─agentDependency # agent依赖文件 - │ libpcap-devel-1.5.3-12.el7.x86_64.rpm # lipcap - │ nmap-7.80-1.x86_64.rpm # nmap,可自己去下最新的,名字也要修改一样 - │ ├─db # 初始化后的数据文件 │ magicude.sql ****执行GenPass.jar后生成**** │ @@ -132,59 +132,17 @@ deploy stopCenterService.sh # 停止center所有服务:eurekaapp.jar centerapp.jar agentapp.jar ``` -### ```MagiCude```目录下 配置文件修改 - -#### agent.yml - -**agent与center部署在同一台服务器**(示例见README.md) - -agent.yml需要修改center节点中的ip,然后跳到**前端api接口地址** - -**agent与center部署在不同服务器(多agent部署)** - -需要手动修改agent.yml文件,修改内容如下,且每个agent.jar对应一个agent.yml配置文件 - -1. task name 需要唯一 -2. rabbitmq host 需要修改成部署centerapp.jar服务器的ip -3. redis host 需要修改成部署centerapp.jar服务器的ip -4. defaultZone中的ip要修改成部署center服务器ip(运行eurekaapp.jar服务器的ip) -5. center中的ip需要修改成部署centerapp.jar服务器的ip - -```yml -# 只列出需要修改的配置,其他配置忽略 -task: - name: agent1 # 多agent部署时task name需要唯一 -spring: - rabbitmq: - host: 127.0.0.1 # 需要修改成部署centerapp.jar服务器的ip - redis: - host: 127.0.0.1 # 需要修改成部署centerapp.jar服务器的ip - -eureka: - client: - service-url: - defaultZone: http://${eureka.user.name}:${eureka.user.password}@127.0.0.1:8686/eureka # 127.0.0.1需要改成部署eurekaapp.jar服务器的ip - -center: - httpValidateApi: http://127.0.0.1:9001/center/pluginchecker # 需要修改成部署centerapp.jar服务器的ip - dnsValidateIp: 127.0.0.1 # 需要修改成部署centerapp.jar服务器的ip -``` - -#### 前端api接口地址 +### center与agent部署 -需要修改```MagiCude\dist\static\js\app.*.js```,* 指的是类似ea5c35e2这样一串字符 +### 生成配置文件 -将```baseURL:"http://127.0.0.1:9001/"```中的ip改成实际部署centerapp.jar的ip,如```baseURL:"http://192.168.12.128:9001/"``` - -### 环境搭建 - -假设服务器已装好,服务器ip地址为```192.168.12.128``` +下载部署包(Releases页面)解压后,deploy目录下双击```GenPass.bat```(Windows下,*uinx/mac直接执行```GenPass.bat```里面的内容就行了),将在当前目录生成newPass.txt,新的配置文件和初始化脚本会自动复制到MagiCude目录下 #### center 1. 将```MagiCude```上传到服务器root目录下 -2. 终端执行```sh initCenterEnvironmentAndStart.sh```,初始化环境和数据并启动系统 +2. 终端执行```sh initCenterEnvironmentAndStart.sh```,初始化环境和数据并启动系统,按提示选择center的ip即可 运行后会在当前目录生成一个center文件夹,里面是center的日志 @@ -215,15 +173,16 @@ systemctl restart docker 1. agent服务器的root目录下新建```MagiCude```目录,将以下文件上传到```MagiCude```目录 ```shell -修改后的agent.yml +agent.yml agentapp.jar initAgentEnvironmentAndStart.sh runAgent.sh stopAgent.sh +uninstall.sh util.sh ``` -2. 然后执行初始化agent环境并启动agent +2. 然后执行初始化agent环境并启动agent,按提示输入center的ip即可 ```shell sh initAgentEnvironmentAndStart.sh @@ -1075,6 +1034,7 @@ mac地址、OS类型、OS版本、类型字段暂时没有使用 **注意:OracleWeakPass插件会导致oracle账户锁定...建议不要在生产环境使用** * python3 selfd自定义插件 + | 插件 | 漏洞名称 | | :-----------------: | :----------------------------: | | FTPWeakPass | FTP弱密码/未授权访问 | @@ -1087,6 +1047,7 @@ mac地址、OS类型、OS版本、类型字段暂时没有使用 | ZookeeperEnvi | Zookeeper未授权访问 | * json selfd自定义插件(插件名需以HTTP开头) + | 插件 | 漏洞名称 | | :---------------------: | :------: | | HTTPElasticsearchUnauth | 默认 | diff --git "a/\344\275\277\347\224\250\350\257\264\346\230\216\345\233\2761/\351\200\211\346\213\251ip.png" "b/\344\275\277\347\224\250\350\257\264\346\230\216\345\233\2761/\351\200\211\346\213\251ip.png" new file mode 100644 index 0000000000000000000000000000000000000000..ff700814f047903d070c097fcbfef87a9b177c9f GIT binary patch literal 41340 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