mirror of
https://github.com/yyhuni/xingrin.git
synced 2026-01-31 11:46:16 +08:00
Compare commits
12 Commits
v1.5.7-dev
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8a5e0cea8 | ||
|
|
3308908d7a | ||
|
|
a8402cfffa | ||
|
|
dce4e12667 | ||
|
|
bd1dd2c0d5 | ||
|
|
0b6560ac17 | ||
|
|
943a4cb960 | ||
|
|
eb2d853b76 | ||
|
|
1184c18b74 | ||
|
|
8a6f1b6f24 | ||
|
|
255d505aba | ||
|
|
d06a9bab1f |
129
README.md
129
README.md
@@ -1,7 +1,7 @@
|
|||||||
<h1 align="center">XingRin - 星环</h1>
|
<h1 align="center">XingRin - 星环</h1>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<b>🛡️ 攻击面管理平台 (ASM) | 自动化资产发现与漏洞扫描系统</b>
|
<b>攻击面管理平台 (ASM) | 自动化资产发现与漏洞扫描系统</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -12,29 +12,28 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="#-功能特性">功能特性</a> •
|
<a href="#功能特性">功能特性</a> •
|
||||||
<a href="#-全局资产搜索">资产搜索</a> •
|
<a href="#全局资产搜索">资产搜索</a> •
|
||||||
<a href="#-快速开始">快速开始</a> •
|
<a href="#快速开始">快速开始</a> •
|
||||||
<a href="#-文档">文档</a> •
|
<a href="#文档">文档</a> •
|
||||||
<a href="#-反馈与贡献">反馈与贡献</a>
|
<a href="#反馈与贡献">反馈与贡献</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<sub>🔍 关键词: ASM | 攻击面管理 | 漏洞扫描 | 资产发现 | 资产搜索 | Bug Bounty | 渗透测试 | Nuclei | 子域名枚举 | EASM</sub>
|
<sub>关键词: ASM | 攻击面管理 | 漏洞扫描 | 资产发现 | 资产搜索 | Bug Bounty | 渗透测试 | Nuclei | 子域名枚举 | EASM</sub>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
## 在线 Demo
|
||||||
## 🌐 在线 Demo
|
|
||||||
|
|
||||||
**[https://xingrin.vercel.app/](https://xingrin.vercel.app/)**
|
**[https://xingrin.vercel.app/](https://xingrin.vercel.app/)**
|
||||||
|
|
||||||
> ⚠️ 仅用于 UI 展示,未接入后端数据库
|
> 仅用于 UI 展示,未接入后端数据库
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<b>🎨 现代化 UI </b>
|
<b>现代化 UI</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -44,45 +43,45 @@
|
|||||||
<img src="docs/screenshots/quantum-rose.png" alt="Quantum Rose" width="24%">
|
<img src="docs/screenshots/quantum-rose.png" alt="Quantum Rose" width="24%">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## 📚 文档
|
## 文档
|
||||||
|
|
||||||
- [📖 技术文档](./docs/README.md) - 技术文档导航(🚧 持续完善中)
|
- [技术文档](./docs/README.md) - 技术文档导航(持续完善中)
|
||||||
- [🚀 快速开始](./docs/quick-start.md) - 一键安装和部署指南
|
- [快速开始](./docs/quick-start.md) - 一键安装和部署指南
|
||||||
- [🔄 版本管理](./docs/version-management.md) - Git Tag 驱动的自动化版本管理系统
|
- [版本管理](./docs/version-management.md) - Git Tag 驱动的自动化版本管理系统
|
||||||
- [📦 Nuclei 模板架构](./docs/nuclei-template-architecture.md) - 模板仓库的存储与同步
|
- [Nuclei 模板架构](./docs/nuclei-template-architecture.md) - 模板仓库的存储与同步
|
||||||
- [📖 字典文件架构](./docs/wordlist-architecture.md) - 字典文件的存储与同步
|
- [字典文件架构](./docs/wordlist-architecture.md) - 字典文件的存储与同步
|
||||||
- [🔍 扫描流程架构](./docs/scan-flow-architecture.md) - 完整扫描流程与工具编排
|
- [扫描流程架构](./docs/scan-flow-architecture.md) - 完整扫描流程与工具编排
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✨ 功能特性
|
## 功能特性
|
||||||
|
|
||||||
### 扫描能力
|
### 扫描能力
|
||||||
|
|
||||||
| 功能 | 状态 | 工具 | 说明 |
|
| 功能 | 状态 | 工具 | 说明 |
|
||||||
|------|------|------|------|
|
|------|------|------|------|
|
||||||
| 子域名扫描 | ✅ | Subfinder, Amass, PureDNS | 被动收集 + 主动爆破,聚合 50+ 数据源 |
|
| 子域名扫描 | 已完成 | Subfinder, Amass, PureDNS | 被动收集 + 主动爆破,聚合 50+ 数据源 |
|
||||||
| 端口扫描 | ✅ | Naabu | 自定义端口范围 |
|
| 端口扫描 | 已完成 | Naabu | 自定义端口范围 |
|
||||||
| 站点发现 | ✅ | HTTPX | HTTP 探测,自动获取标题、状态码、技术栈 |
|
| 站点发现 | 已完成 | HTTPX | HTTP 探测,自动获取标题、状态码、技术栈 |
|
||||||
| 指纹识别 | ✅ | XingFinger | 2.7W+ 指纹规则,多源指纹库 |
|
| 指纹识别 | 已完成 | XingFinger | 2.7W+ 指纹规则,多源指纹库 |
|
||||||
| URL 收集 | ✅ | Waymore, Katana | 历史数据 + 主动爬取 |
|
| URL 收集 | 已完成 | Waymore, Katana | 历史数据 + 主动爬取 |
|
||||||
| 目录扫描 | ✅ | FFUF | 高速爆破,智能字典 |
|
| 目录扫描 | 已完成 | FFUF | 高速爆破,智能字典 |
|
||||||
| 漏洞扫描 | ✅ | Nuclei, Dalfox | 9000+ POC 模板,XSS 检测 |
|
| 漏洞扫描 | 已完成 | Nuclei, Dalfox | 9000+ POC 模板,XSS 检测 |
|
||||||
| 站点截图 | ✅ | Playwright | WebP 高压缩存储 |
|
| 站点截图 | 已完成 | Playwright | WebP 高压缩存储 |
|
||||||
|
|
||||||
### 平台能力
|
### 平台能力
|
||||||
|
|
||||||
| 功能 | 状态 | 说明 |
|
| 功能 | 状态 | 说明 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
| 目标管理 | ✅ | 多层级组织,支持域名/IP 目标 |
|
| 目标管理 | 已完成 | 多层级组织,支持域名/IP 目标 |
|
||||||
| 资产快照 | ✅ | 扫描结果对比,追踪资产变化 |
|
| 资产快照 | 已完成 | 扫描结果对比,追踪资产变化 |
|
||||||
| 黑名单过滤 | ✅ | 全局 + Target 级,支持通配符/CIDR |
|
| 黑名单过滤 | 已完成 | 全局 + Target 级,支持通配符/CIDR |
|
||||||
| 定时任务 | ✅ | Cron 表达式,自动化周期扫描 |
|
| 定时任务 | 已完成 | Cron 表达式,自动化周期扫描 |
|
||||||
| 分布式扫描 | ✅ | 多 Worker 节点,负载感知调度 |
|
| 分布式扫描 | 已完成 | 多 Worker 节点,负载感知调度 |
|
||||||
| 全局搜索 | ✅ | 表达式语法,多字段组合查询 |
|
| 全局搜索 | 已完成 | 表达式语法,多字段组合查询 |
|
||||||
| 通知推送 | ✅ | 企业微信、Telegram、Discord |
|
| 通知推送 | 已完成 | 企业微信、Telegram、Discord |
|
||||||
| API 密钥管理 | ✅ | 可视化配置各数据源 API Key |
|
| API 密钥管理 | 已完成 | 可视化配置各数据源 API Key |
|
||||||
|
|
||||||
### 扫描流程架构
|
### 扫描流程架构
|
||||||
|
|
||||||
@@ -136,7 +135,7 @@ flowchart LR
|
|||||||
|
|
||||||
详细说明请查看 [扫描流程架构文档](./docs/scan-flow-architecture.md)
|
详细说明请查看 [扫描流程架构文档](./docs/scan-flow-architecture.md)
|
||||||
|
|
||||||
### 🖥️ 分布式架构
|
### 分布式架构
|
||||||
- **多节点扫描** - 支持部署多个 Worker 节点,横向扩展扫描能力
|
- **多节点扫描** - 支持部署多个 Worker 节点,横向扩展扫描能力
|
||||||
- **本地节点** - 零配置,安装即自动注册本地 Docker Worker
|
- **本地节点** - 零配置,安装即自动注册本地 Docker Worker
|
||||||
- **远程节点** - SSH 一键部署远程 VPS 作为扫描节点
|
- **远程节点** - SSH 一键部署远程 VPS 作为扫描节点
|
||||||
@@ -181,7 +180,7 @@ flowchart TB
|
|||||||
W3 -.心跳上报.-> REDIS
|
W3 -.心跳上报.-> REDIS
|
||||||
```
|
```
|
||||||
|
|
||||||
### 🔎 全局资产搜索
|
### 全局资产搜索
|
||||||
- **多类型搜索** - 支持 Website 和 Endpoint 两种资产类型
|
- **多类型搜索** - 支持 Website 和 Endpoint 两种资产类型
|
||||||
- **表达式语法** - 支持 `=`(模糊)、`==`(精确)、`!=`(不等于)操作符
|
- **表达式语法** - 支持 `=`(模糊)、`==`(精确)、`!=`(不等于)操作符
|
||||||
- **逻辑组合** - 支持 `&&` (AND) 和 `||` (OR) 逻辑组合
|
- **逻辑组合** - 支持 `&&` (AND) 和 `||` (OR) 逻辑组合
|
||||||
@@ -205,14 +204,14 @@ host="admin" && tech="php" && status=="200"
|
|||||||
url="/api/v1" && status!="404"
|
url="/api/v1" && status!="404"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 📊 可视化界面
|
### 可视化界面
|
||||||
- **数据统计** - 资产/漏洞统计仪表盘
|
- **数据统计** - 资产/漏洞统计仪表盘
|
||||||
- **实时通知** - WebSocket 消息推送
|
- **实时通知** - WebSocket 消息推送
|
||||||
- **通知推送** - 实时企业微信,tg,discard消息推送服务
|
- **通知推送** - 实时企业微信,tg,discard消息推送服务
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📦 快速开始
|
## 快速开始
|
||||||
|
|
||||||
### 环境要求
|
### 环境要求
|
||||||
|
|
||||||
@@ -230,11 +229,11 @@ cd xingrin
|
|||||||
# 安装并启动(生产模式)
|
# 安装并启动(生产模式)
|
||||||
sudo ./install.sh
|
sudo ./install.sh
|
||||||
|
|
||||||
# 🇨🇳 中国大陆用户推荐使用镜像加速(第三方加速服务可能会失效,不保证长期可用)
|
# 中国大陆用户推荐使用镜像加速(第三方加速服务可能会失效,不保证长期可用)
|
||||||
sudo ./install.sh --mirror
|
sudo ./install.sh --mirror
|
||||||
```
|
```
|
||||||
|
|
||||||
> **💡 --mirror 参数说明**
|
> **--mirror 参数说明**
|
||||||
> - 自动配置 Docker 镜像加速(国内镜像源)
|
> - 自动配置 Docker 镜像加速(国内镜像源)
|
||||||
> - 加速 Git 仓库克隆(Nuclei 模板等)
|
> - 加速 Git 仓库克隆(Nuclei 模板等)
|
||||||
|
|
||||||
@@ -259,17 +258,17 @@ sudo ./restart.sh
|
|||||||
sudo ./uninstall.sh
|
sudo ./uninstall.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🤝 反馈与贡献
|
## 反馈与贡献
|
||||||
|
|
||||||
- 💡 **发现 Bug,有新想法,比如UI设计,功能设计等** 欢迎点击右边链接进行提交建议 [Issue](https://github.com/yyhuni/xingrin/issues) 或者公众号私信
|
- **发现 Bug,有新想法,比如UI设计,功能设计等** 欢迎点击右边链接进行提交建议 [Issue](https://github.com/yyhuni/xingrin/issues) 或者公众号私信
|
||||||
|
|
||||||
## 📧 联系
|
## 联系
|
||||||
- 微信公众号: **塔罗安全学苑**
|
- 微信公众号: **塔罗安全学苑**
|
||||||
- 微信群去公众号底下的菜单,有个交流群,点击就可以看到了,链接过期可以私信我拉你
|
- 微信群去公众号底下的菜单,有个交流群,点击就可以看到了,链接过期可以私信我拉你
|
||||||
|
|
||||||
<img src="docs/wechat-qrcode.png" alt="微信公众号" width="200">
|
<img src="docs/wechat-qrcode.png" alt="微信公众号" width="200">
|
||||||
|
|
||||||
### 🎁 关注公众号免费领取指纹库
|
### 关注公众号免费领取指纹库
|
||||||
|
|
||||||
| 指纹库 | 数量 |
|
| 指纹库 | 数量 |
|
||||||
|--------|------|
|
|--------|------|
|
||||||
@@ -278,9 +277,9 @@ sudo ./uninstall.sh
|
|||||||
| goby.json | 7,086 |
|
| goby.json | 7,086 |
|
||||||
| FingerprintHub.json | 3,147 |
|
| FingerprintHub.json | 3,147 |
|
||||||
|
|
||||||
> 💡 关注公众号回复「指纹」即可获取
|
> 关注公众号回复「指纹」即可获取
|
||||||
|
|
||||||
## ☕ 赞助支持
|
## 赞助支持
|
||||||
|
|
||||||
如果这个项目对你有帮助,谢谢请我能喝杯蜜雪冰城,你的star和赞助是我免费更新的动力
|
如果这个项目对你有帮助,谢谢请我能喝杯蜜雪冰城,你的star和赞助是我免费更新的动力
|
||||||
|
|
||||||
@@ -289,14 +288,9 @@ sudo ./uninstall.sh
|
|||||||
<img src="docs/zfb_pay.jpg" alt="支付宝" width="200">
|
<img src="docs/zfb_pay.jpg" alt="支付宝" width="200">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
### 🙏 感谢以下赞助
|
|
||||||
|
|
||||||
| 昵称 | 金额 |
|
|
||||||
|------|------|
|
|
||||||
| X(闭关中) | ¥88 |
|
|
||||||
|
|
||||||
|
|
||||||
## ⚠️ 免责声明
|
## 免责声明
|
||||||
|
|
||||||
**重要:请在使用前仔细阅读**
|
**重要:请在使用前仔细阅读**
|
||||||
|
|
||||||
@@ -311,30 +305,29 @@ sudo ./uninstall.sh
|
|||||||
- 遵守所在地区的法律法规
|
- 遵守所在地区的法律法规
|
||||||
- 承担因滥用产生的一切后果
|
- 承担因滥用产生的一切后果
|
||||||
|
|
||||||
## 🌟 Star History
|
## Star History
|
||||||
|
|
||||||
如果这个项目对你有帮助,请给一个 ⭐ Star 支持一下!
|
如果这个项目对你有帮助,请给一个 Star 支持一下!
|
||||||
|
|
||||||
[](https://star-history.com/#yyhuni/xingrin&Date)
|
[](https://star-history.com/#yyhuni/xingrin&Date)
|
||||||
|
|
||||||
## 📄 许可证
|
## 许可证
|
||||||
|
|
||||||
本项目采用 [GNU General Public License v3.0](LICENSE) 许可证。
|
本项目采用 [GNU General Public License v3.0](LICENSE) 许可证。
|
||||||
|
|
||||||
### 允许的用途
|
### 允许的用途
|
||||||
|
|
||||||
- ✅ 个人学习和研究
|
- 个人学习和研究
|
||||||
- ✅ 商业和非商业使用
|
- 商业和非商业使用
|
||||||
- ✅ 修改和分发
|
- 修改和分发
|
||||||
- ✅ 专利使用
|
- 专利使用
|
||||||
- ✅ 私人使用
|
- 私人使用
|
||||||
|
|
||||||
### 义务和限制
|
### 义务和限制
|
||||||
|
|
||||||
- 📋 **开源义务**:分发时必须提供源代码
|
- **开源义务**:分发时必须提供源代码
|
||||||
- 📋 **相同许可**:衍生作品必须使用相同许可证
|
- **相同许可**:衍生作品必须使用相同许可证
|
||||||
- 📋 **版权声明**:必须保留原始版权和许可证声明
|
- **版权声明**:必须保留原始版权和许可证声明
|
||||||
- ❌ **责任免除**:不提供任何担保
|
- **责任免除**:不提供任何担保
|
||||||
- ❌ 未经授权的渗透测试
|
- 未经授权的渗透测试
|
||||||
- ❌ 任何违法行为
|
- 任何违法行为
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
初始化默认扫描引擎
|
初始化默认扫描引擎
|
||||||
|
|
||||||
用法:
|
用法:
|
||||||
python manage.py init_default_engine # 只创建不存在的引擎(不覆盖已有)
|
python manage.py init_default_engine # 只创建不存在的引擎(不覆盖已有)
|
||||||
python manage.py init_default_engine --force # 强制覆盖所有引擎配置
|
python manage.py init_default_engine --force # 强制覆盖所有引擎配置
|
||||||
|
python manage.py init_default_engine --force-sub # 只覆盖子引擎,保留 full scan
|
||||||
|
|
||||||
cd /root/my-vulun-scan/docker
|
cd /root/my-vulun-scan/docker
|
||||||
docker compose exec server python backend/manage.py init_default_engine --force
|
docker compose exec server python backend/manage.py init_default_engine --force
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
- 读取 engine_config_example.yaml 作为默认配置
|
- 读取 engine_config_example.yaml 作为默认配置
|
||||||
- 创建 full scan(默认引擎)+ 各扫描类型的子引擎
|
- 创建 full scan(默认引擎)+ 各扫描类型的子引擎
|
||||||
- 默认不覆盖已有配置,加 --force 才会覆盖
|
- 默认不覆盖已有配置,加 --force 才会覆盖
|
||||||
|
- 加 --force-sub 只覆盖子引擎配置,保留用户自定义的 full scan
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
@@ -30,11 +32,18 @@ class Command(BaseCommand):
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--force',
|
'--force',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='强制覆盖已有的引擎配置',
|
help='强制覆盖已有的引擎配置(包括 full scan 和子引擎)',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--force-sub',
|
||||||
|
action='store_true',
|
||||||
|
help='只覆盖子引擎配置,保留 full scan(升级时使用)',
|
||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
force = options.get('force', False)
|
force = options.get('force', False)
|
||||||
|
force_sub = options.get('force_sub', False)
|
||||||
|
|
||||||
# 读取默认配置文件
|
# 读取默认配置文件
|
||||||
config_path = Path(__file__).resolve().parent.parent.parent.parent / 'scan' / 'configs' / 'engine_config_example.yaml'
|
config_path = Path(__file__).resolve().parent.parent.parent.parent / 'scan' / 'configs' / 'engine_config_example.yaml'
|
||||||
|
|
||||||
@@ -99,15 +108,22 @@ class Command(BaseCommand):
|
|||||||
engine_name = f"{scan_type}"
|
engine_name = f"{scan_type}"
|
||||||
sub_engine = ScanEngine.objects.filter(name=engine_name).first()
|
sub_engine = ScanEngine.objects.filter(name=engine_name).first()
|
||||||
if sub_engine:
|
if sub_engine:
|
||||||
if force:
|
# force 或 force_sub 都会覆盖子引擎
|
||||||
|
if force or force_sub:
|
||||||
sub_engine.configuration = single_yaml
|
sub_engine.configuration = single_yaml
|
||||||
sub_engine.save()
|
sub_engine.save()
|
||||||
self.stdout.write(self.style.SUCCESS(f' ✓ 子引擎 {engine_name} 配置已更新 (ID: {sub_engine.id})'))
|
self.stdout.write(self.style.SUCCESS(
|
||||||
|
f' ✓ 子引擎 {engine_name} 配置已更新 (ID: {sub_engine.id})'
|
||||||
|
))
|
||||||
else:
|
else:
|
||||||
self.stdout.write(self.style.WARNING(f' ⊘ {engine_name} 已存在,跳过(使用 --force 覆盖)'))
|
self.stdout.write(self.style.WARNING(
|
||||||
|
f' ⊘ {engine_name} 已存在,跳过(使用 --force 覆盖)'
|
||||||
|
))
|
||||||
else:
|
else:
|
||||||
sub_engine = ScanEngine.objects.create(
|
sub_engine = ScanEngine.objects.create(
|
||||||
name=engine_name,
|
name=engine_name,
|
||||||
configuration=single_yaml,
|
configuration=single_yaml,
|
||||||
)
|
)
|
||||||
self.stdout.write(self.style.SUCCESS(f' ✓ 子引擎 {engine_name} 已创建 (ID: {sub_engine.id})'))
|
self.stdout.write(self.style.SUCCESS(
|
||||||
|
f' ✓ 子引擎 {engine_name} 已创建 (ID: {sub_engine.id})'
|
||||||
|
))
|
||||||
|
|||||||
@@ -83,20 +83,20 @@ if not yaml_path.exists():
|
|||||||
print('未找到配置文件,跳过')
|
print('未找到配置文件,跳过')
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
|
new_config = yaml_path.read_text()
|
||||||
|
|
||||||
# 检查是否已有 full scan 引擎
|
# 检查是否已有 full scan 引擎
|
||||||
engine = ScanEngine.objects.filter(name='full scan').first()
|
engine = ScanEngine.objects.filter(name='full scan').first()
|
||||||
if engine:
|
if engine:
|
||||||
if not engine.configuration or not engine.configuration.strip():
|
# 直接覆盖为最新配置
|
||||||
engine.configuration = yaml_path.read_text()
|
engine.configuration = new_config
|
||||||
engine.save(update_fields=['configuration'])
|
engine.save(update_fields=['configuration'])
|
||||||
print(f'已初始化引擎配置: {engine.name}')
|
print(f'已更新引擎配置: {engine.name}')
|
||||||
else:
|
|
||||||
print(f'引擎已有配置,跳过')
|
|
||||||
else:
|
else:
|
||||||
# 创建引擎
|
# 创建引擎
|
||||||
engine = ScanEngine.objects.create(
|
engine = ScanEngine.objects.create(
|
||||||
name='full scan',
|
name='full scan',
|
||||||
configuration=yaml_path.read_text(),
|
configuration=new_config,
|
||||||
)
|
)
|
||||||
print(f'已创建引擎: {engine.name}')
|
print(f'已创建引擎: {engine.name}')
|
||||||
"
|
"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ python manage.py migrate --noinput
|
|||||||
echo " ✓ 数据库迁移完成"
|
echo " ✓ 数据库迁移完成"
|
||||||
|
|
||||||
echo " [1.1/3] 初始化默认扫描引擎..."
|
echo " [1.1/3] 初始化默认扫描引擎..."
|
||||||
python manage.py init_default_engine
|
python manage.py init_default_engine --force
|
||||||
echo " ✓ 默认扫描引擎已就绪"
|
echo " ✓ 默认扫描引擎已就绪"
|
||||||
|
|
||||||
echo " [1.2/3] 初始化默认目录字典..."
|
echo " [1.2/3] 初始化默认目录字典..."
|
||||||
|
|||||||
@@ -191,8 +191,3 @@ else
|
|||||||
echo " cd frontend && pnpm dev"
|
echo " cd frontend && pnpm dev"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${BOLD}默认账号${NC}"
|
|
||||||
echo " 用户名: admin"
|
|
||||||
echo " 密码: admin"
|
|
||||||
echo -e " ${YELLOW}[!] 请首次登录后修改密码${NC}"
|
|
||||||
echo ""
|
|
||||||
|
|||||||
@@ -58,14 +58,6 @@ subdomain_discovery:
|
|||||||
enabled: true
|
enabled: true
|
||||||
timeout: 600 # 10 minutes (required)
|
timeout: 600 # 10 minutes (required)
|
||||||
|
|
||||||
amass_passive:
|
|
||||||
enabled: true
|
|
||||||
timeout: 600 # 10 minutes (required)
|
|
||||||
|
|
||||||
amass_active:
|
|
||||||
enabled: true
|
|
||||||
timeout: 1800 # 30 minutes (required)
|
|
||||||
|
|
||||||
sublist3r:
|
sublist3r:
|
||||||
enabled: true
|
enabled: true
|
||||||
timeout: 900 # 15 minutes (required)
|
timeout: 900 # 15 minutes (required)
|
||||||
|
|||||||
108
update.sh
108
update.sh
@@ -21,8 +21,8 @@ cd "$(dirname "$0")"
|
|||||||
|
|
||||||
# 权限检查
|
# 权限检查
|
||||||
if [ "$EUID" -ne 0 ]; then
|
if [ "$EUID" -ne 0 ]; then
|
||||||
echo -e "\033[0;31m[错误] 请使用 sudo 运行此脚本\033[0m"
|
printf "\033[0;31m✗ 请使用 sudo 运行此脚本\033[0m\n"
|
||||||
echo -e " 正确用法: \033[1msudo ./update.sh\033[0m"
|
printf " 正确用法: \033[1msudo ./update.sh\033[0m\n"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -49,9 +49,17 @@ YELLOW='\033[1;33m'
|
|||||||
RED='\033[0;31m'
|
RED='\033[0;31m'
|
||||||
BLUE='\033[0;34m'
|
BLUE='\033[0;34m'
|
||||||
CYAN='\033[0;36m'
|
CYAN='\033[0;36m'
|
||||||
|
DIM='\033[2m'
|
||||||
BOLD='\033[1m'
|
BOLD='\033[1m'
|
||||||
NC='\033[0m'
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# 日志函数
|
||||||
|
log_step() { printf "${CYAN}▶${NC} %s\n" "$1"; }
|
||||||
|
log_ok() { printf " ${GREEN}✓${NC} %s\n" "$1"; }
|
||||||
|
log_info() { printf " ${DIM}→${NC} %s\n" "$1"; }
|
||||||
|
log_warn() { printf " ${YELLOW}!${NC} %s\n" "$1"; }
|
||||||
|
log_error() { printf "${RED}✗${NC} %s\n" "$1"; }
|
||||||
|
|
||||||
# 合并 .env 新配置项(保留用户已有值)
|
# 合并 .env 新配置项(保留用户已有值)
|
||||||
merge_env_config() {
|
merge_env_config() {
|
||||||
local example_file="docker/.env.example"
|
local example_file="docker/.env.example"
|
||||||
@@ -70,58 +78,68 @@ merge_env_config() {
|
|||||||
|
|
||||||
if ! grep -q "^${key}=" "$env_file"; then
|
if ! grep -q "^${key}=" "$env_file"; then
|
||||||
printf '%s\n' "$line" >> "$env_file"
|
printf '%s\n' "$line" >> "$env_file"
|
||||||
echo -e " ${GREEN}+${NC} 新增: $key"
|
log_info "新增配置: $key"
|
||||||
((new_keys++))
|
((new_keys++))
|
||||||
fi
|
fi
|
||||||
done < "$example_file"
|
done < "$example_file"
|
||||||
|
|
||||||
if [ $new_keys -gt 0 ]; then
|
if [ $new_keys -gt 0 ]; then
|
||||||
echo -e " ${GREEN}OK${NC} 已添加 $new_keys 个新配置项"
|
log_ok "已添加 $new_keys 个新配置项"
|
||||||
else
|
else
|
||||||
echo -e " ${GREEN}OK${NC} 配置已是最新"
|
log_ok "配置已是最新"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
echo ""
|
# 显示标题
|
||||||
echo -e "${BOLD}${BLUE}╔════════════════════════════════════════╗${NC}"
|
printf "\n"
|
||||||
|
printf "${BOLD}${BLUE}┌────────────────────────────────────────┐${NC}\n"
|
||||||
if [ "$DEV_MODE" = true ]; then
|
if [ "$DEV_MODE" = true ]; then
|
||||||
echo -e "${BOLD}${BLUE}║ 开发环境更新(本地构建) ║${NC}"
|
printf "${BOLD}${BLUE}│${NC} ${BOLD}XingRin 系统更新${NC} ${BOLD}${BLUE}│${NC}\n"
|
||||||
|
printf "${BOLD}${BLUE}│${NC} ${DIM}开发模式 · 本地构建${NC} ${BOLD}${BLUE}│${NC}\n"
|
||||||
else
|
else
|
||||||
echo -e "${BOLD}${BLUE}║ 生产环境更新(Docker Hub) ║${NC}"
|
printf "${BOLD}${BLUE}│${NC} ${BOLD}XingRin 系统更新${NC} ${BOLD}${BLUE}│${NC}\n"
|
||||||
|
printf "${BOLD}${BLUE}│${NC} ${DIM}生产模式 · Docker Hub${NC} ${BOLD}${BLUE}│${NC}\n"
|
||||||
fi
|
fi
|
||||||
echo -e "${BOLD}${BLUE}╚════════════════════════════════════════╝${NC}"
|
printf "${BOLD}${BLUE}└────────────────────────────────────────┘${NC}\n"
|
||||||
echo ""
|
printf "\n"
|
||||||
|
|
||||||
# 测试性功能警告
|
# 警告提示
|
||||||
echo -e "${BOLD}${YELLOW}[!] 警告:此功能为测试性功能,可能会导致升级失败${NC}"
|
printf "${YELLOW}┌─ 注意事项 ─────────────────────────────┐${NC}\n"
|
||||||
echo -e "${YELLOW} 建议运行 ./uninstall.sh 后重新clone最新代码进行全新安装${NC}"
|
printf "${YELLOW}│${NC} • 此功能为测试性功能,可能导致升级失败 ${YELLOW}│${NC}\n"
|
||||||
echo ""
|
printf "${YELLOW}│${NC} • 升级会覆盖所有默认引擎配置 ${YELLOW}│${NC}\n"
|
||||||
echo -n -e "${YELLOW}是否继续更新?(y/N) ${NC}"
|
printf "${YELLOW}│${NC} • 自定义配置请先备份或创建新引擎 ${YELLOW}│${NC}\n"
|
||||||
|
printf "${YELLOW}│${NC} • 推荐:卸载后重新安装以获得最佳体验 ${YELLOW}│${NC}\n"
|
||||||
|
printf "${YELLOW}└────────────────────────────────────────┘${NC}\n"
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
|
printf "${YELLOW}是否继续更新?${NC} [y/N] "
|
||||||
read -r ans_continue
|
read -r ans_continue
|
||||||
ans_continue=${ans_continue:-N}
|
ans_continue=${ans_continue:-N}
|
||||||
|
|
||||||
if [[ ! $ans_continue =~ ^[Yy]$ ]]; then
|
if [[ ! $ans_continue =~ ^[Yy]$ ]]; then
|
||||||
echo -e "${CYAN}已取消更新。${NC}"
|
printf "\n${DIM}已取消更新${NC}\n"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
echo ""
|
printf "\n"
|
||||||
|
|
||||||
# Step 1: 停止服务
|
# Step 1: 停止服务
|
||||||
echo -e "${CYAN}[1/5]${NC} 停止服务..."
|
log_step "停止服务..."
|
||||||
./stop.sh 2>&1 | sed 's/^/ /'
|
./stop.sh 2>&1 | sed 's/^/ /'
|
||||||
|
log_ok "服务已停止"
|
||||||
|
|
||||||
# Step 2: 拉取代码
|
# Step 2: 拉取代码
|
||||||
echo ""
|
printf "\n"
|
||||||
echo -e "${CYAN}[2/5]${NC} 拉取代码..."
|
log_step "拉取最新代码..."
|
||||||
git pull --rebase 2>&1 | sed 's/^/ /'
|
if git pull --rebase 2>&1 | sed 's/^/ /'; then
|
||||||
if [ $? -ne 0 ]; then
|
log_ok "代码已更新"
|
||||||
echo -e "${RED}[错误]${NC} git pull 失败,请手动解决冲突后重试"
|
else
|
||||||
|
log_error "git pull 失败,请手动解决冲突后重试"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Step 3: 检查配置更新 + 版本同步
|
# Step 3: 检查配置更新 + 版本同步
|
||||||
echo ""
|
printf "\n"
|
||||||
echo -e "${CYAN}[3/5]${NC} 检查配置更新..."
|
log_step "同步配置..."
|
||||||
merge_env_config
|
merge_env_config
|
||||||
|
|
||||||
# 版本同步:从 VERSION 文件更新 IMAGE_TAG
|
# 版本同步:从 VERSION 文件更新 IMAGE_TAG
|
||||||
@@ -130,21 +148,20 @@ if [ -f "VERSION" ]; then
|
|||||||
if [ -n "$NEW_VERSION" ]; then
|
if [ -n "$NEW_VERSION" ]; then
|
||||||
if grep -q "^IMAGE_TAG=" "docker/.env"; then
|
if grep -q "^IMAGE_TAG=" "docker/.env"; then
|
||||||
sed_inplace "s/^IMAGE_TAG=.*/IMAGE_TAG=$NEW_VERSION/" "docker/.env"
|
sed_inplace "s/^IMAGE_TAG=.*/IMAGE_TAG=$NEW_VERSION/" "docker/.env"
|
||||||
echo -e " ${GREEN}+${NC} 版本同步: IMAGE_TAG=$NEW_VERSION"
|
|
||||||
else
|
else
|
||||||
printf '%s\n' "IMAGE_TAG=$NEW_VERSION" >> "docker/.env"
|
printf '%s\n' "IMAGE_TAG=$NEW_VERSION" >> "docker/.env"
|
||||||
echo -e " ${GREEN}+${NC} 新增版本: IMAGE_TAG=$NEW_VERSION"
|
|
||||||
fi
|
fi
|
||||||
|
log_ok "版本同步: $NEW_VERSION"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Step 4: 构建/拉取镜像
|
# Step 4: 构建/拉取镜像
|
||||||
echo ""
|
printf "\n"
|
||||||
echo -e "${CYAN}[4/5]${NC} 更新镜像..."
|
log_step "更新镜像..."
|
||||||
|
|
||||||
if [ "$DEV_MODE" = true ]; then
|
if [ "$DEV_MODE" = true ]; then
|
||||||
# 开发模式:本地构建所有镜像(包括 Worker)
|
# 开发模式:本地构建所有镜像(包括 Worker)
|
||||||
echo -e " 构建 Worker 镜像..."
|
log_info "构建 Worker 镜像..."
|
||||||
|
|
||||||
# 读取 IMAGE_TAG
|
# 读取 IMAGE_TAG
|
||||||
IMAGE_TAG=$(grep "^IMAGE_TAG=" "docker/.env" | cut -d'=' -f2)
|
IMAGE_TAG=$(grep "^IMAGE_TAG=" "docker/.env" | cut -d'=' -f2)
|
||||||
@@ -153,24 +170,23 @@ if [ "$DEV_MODE" = true ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# 构建 Worker 镜像(Worker 是临时容器,不在 compose 中,需要单独构建)
|
# 构建 Worker 镜像(Worker 是临时容器,不在 compose 中,需要单独构建)
|
||||||
docker build -t docker-worker -f docker/worker/Dockerfile . 2>&1 | sed 's/^/ /'
|
docker build -t docker-worker -f docker/worker/Dockerfile . 2>&1 | sed 's/^/ /'
|
||||||
docker tag docker-worker docker-worker:${IMAGE_TAG} 2>&1 | sed 's/^/ /'
|
docker tag docker-worker docker-worker:${IMAGE_TAG} 2>&1 | sed 's/^/ /'
|
||||||
echo -e " ${GREEN}OK${NC} Worker 镜像已构建: docker-worker:${IMAGE_TAG}"
|
log_ok "Worker 镜像: docker-worker:${IMAGE_TAG}"
|
||||||
|
|
||||||
# 其他服务镜像由 start.sh --dev 构建
|
log_info "其他服务镜像将在启动时构建"
|
||||||
echo -e " 其他服务镜像将在启动时构建..."
|
|
||||||
else
|
else
|
||||||
# 生产模式:镜像由 start.sh 拉取
|
log_info "镜像将在启动时从 Docker Hub 拉取"
|
||||||
echo -e " 镜像将在启动时从 Docker Hub 拉取..."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Step 5: 启动服务
|
# Step 5: 启动服务
|
||||||
echo ""
|
printf "\n"
|
||||||
echo -e "${CYAN}[5/5]${NC} 启动服务..."
|
log_step "启动服务..."
|
||||||
./start.sh "$@"
|
./start.sh "$@"
|
||||||
|
|
||||||
echo ""
|
# 完成提示
|
||||||
echo -e "${BOLD}${GREEN}════════════════════════════════════════${NC}"
|
printf "\n"
|
||||||
echo -e "${BOLD}${GREEN} 更新完成!${NC}"
|
printf "${GREEN}┌────────────────────────────────────────┐${NC}\n"
|
||||||
echo -e "${BOLD}${GREEN}════════════════════════════════════════${NC}"
|
printf "${GREEN}│${NC} ${BOLD}${GREEN}✓${NC} ${BOLD}更新完成${NC} ${GREEN}│${NC}\n"
|
||||||
echo ""
|
printf "${GREEN}└────────────────────────────────────────┘${NC}\n"
|
||||||
|
printf "\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user