Vartika-Mishra13/SentinelAI

GitHub: Vartika-Mishra13/SentinelAI

基于 MERN 栈构建的安全 API 网关,提供速率限制、威胁检测、异常评分和实时监控仪表板,保护 API 免受滥用和恶意攻击。

Stars: 0 | Forks: 0

# SentinelAI — AI 驱动的 API 网关与滥用检测系统 SentinelAI 是一个专注于安全的 API 网关,可实时监控流量、检测异常模式并自动封禁恶意客户端。它将滑动窗口速率限制、基于规则的异常评分、威胁检测和 Geo-IP 富化整合为一个单一的可部署系统,并配备了实时管理仪表板。 ## 仪表板 ![仪表板概览](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/30670bbec4204412.png) *显示在一次模拟突发攻击后,实时威胁状态、总请求数、可疑活动和被封禁 IP 的统计面板。* ![实时流量 Feed](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/192c416196204418.png) *实时流量 Feed 展示了状态的演变过程:正常 → 可疑 (3/5 → 4/5 → 5/5) → 已封禁,并附带了具体原因和时间戳。* ## 工作原理 每个传入的请求在到达任何路由之前,都会经过一个中间件链: ``` Request → threatDetection → apiKeyMiddleware / slidingRateLimiter → requestLogger → Route ``` **threatDetection** 使用正则表达式扫描 query params、request body 和 URL,以检测 SQL 注入、XSS 和路径遍历模式。如果匹配到任何模式,将立即返回 400 并予以拦截。 **apiKeyMiddleware** 负责验证 API key,检查该 IP 当前是否被封禁,通过 Redis 为每个用户应用固定窗口的每小时速率限制,并自动封禁超过突发阈值的 IP。 **slidingRateLimiter** 使用 Redis 有序集合来追踪可配置窗口内的请求时间戳。在请求达到阈值被完全封禁之前,接近阈值的请求会被标记为可疑状态 —— 从而在硬性切断之前为仪表板提供预警状态。 **requestLogger** 会在每次请求后运行,无论结果如何。它会对 IP 进行地理富化,计算异常分数(0–100),将日志写入 MongoDB,并在请求被拦截时通过 Nodemailer 发送电子邮件警报。 **anomalyScorer** 根据威胁类型(SQL 注入 +40,XSS +40)、请求状态(已封禁 +20,可疑 +10)、请求频率、发生时间(非工作时间 +10)以及未知地理来源(+10)来分配分数。分数上限为 100,并映射为“正常 / 可疑 / 严重”等级。 ## 功能 - **双重速率限制** — 固定窗口(按用户每小时计算)和滑动窗口(可配置的窗口与限制),可通过模式标志进行切换 - **威胁检测** — 对每个请求进行 SQL 注入、XSS 和路径遍历扫描 - **异常评分** — 基于规则的 0–100 分数,并附带每个请求的可解释原因 - **自动 IP 封禁** — 超过突发阈值的 IP 将被封禁一段可配置的时长 - **Geo-IP 富化** — 使用 ip-api.com 并带有 geoip-lite 回退机制,配备 1 小时的内存缓存 - **电子邮件警报** — 每次请求被封禁时,通过 Nodemailer 发送 HTML 警报邮件 - **规则热配置** — 速率限制、突发阈值、封禁时长存储在 MongoDB 中,可直接在仪表板中修改而无需重新部署 - **管理仪表板** — 支持搜索、分页的实时流量 Feed、IP 封禁管理、API key 管理、请求压力趋势图以及智能警报面板 - **身份验证速率限制** — 登录和注册 endpoint 限制为每 15 分钟最多 10 次尝试 ## 技术栈 | 层级 | 技术 | |---|---| | Frontend | React.js, Recharts, React Toastify | | Backend | Node.js, Express.js | | 数据库 | MongoDB Atlas (Mongoose) | | 缓存 / 速率限制 | Upstash Redis | | 身份验证 | JWT + bcryptjs | | 电子邮件警报 | Nodemailer (Gmail) | | Geo-IP | ip-api.com + geoip-lite | ## 项目结构 ``` SentinelAI/ ├── backend/ │ ├── config/ │ │ └── redis.js # Upstash Redis client │ ├── controllers/ │ │ ├── adminController.js # Dashboard stats, IP/key management, rules │ │ ├── authController.js # Signup, login │ │ └── userController.js # API key generation, usage │ ├── middleware/ │ │ ├── apiKeyMiddleware.js # Fixed window rate limiting + IP blocking │ │ ├── authMiddleware.js # JWT verification │ │ ├── rateLimiter.js # Mode switcher (fixed vs sliding) │ │ ├── requestLogger.js # Logging, anomaly scoring, email alerts │ │ ├── slidingRateLimiter.js # Sliding window rate limiting via Redis │ │ └── threatDetection.js # SQLi, XSS, path traversal scanning │ ├── models/ │ │ ├── BlockedIP.js │ │ ├── RequestLog.js │ │ ├── SecurityRule.js │ │ ├── Usage.js │ │ └── User.js │ ├── routes/ │ │ ├── adminRoutes.js │ │ ├── authRoutes.js # Rate limited (10 attempts / 15 min) │ │ └── userRoutes.js │ ├── utils/ │ │ ├── anomalyScorer.js # 0–100 scoring with explainable reasons │ │ ├── emailAlert.js # HTML alert emails │ │ ├── geoip.js # Geo enrichment with caching │ │ └── securityRules.js # DB-driven rule fetching │ └── server.js ├── frontend/ │ └── src/ │ ├── pages/ │ │ ├── Dashboard.js │ │ ├── Login.js │ │ └── Register.js │ └── components/ │ └── RequestChart.js ├── loadtest.js # Load test script (burst + gradual phases) └── README.md ``` ## 本地运行 ### 前置条件 - Node.js 18+ - MongoDB Atlas 账户(免费版即可) - Upstash Redis 账户(免费版即可) - 启用了应用密码的 Gmail 账户 ### 1. 克隆仓库 ``` git clone https://github.com/Vartika-Mishra13/SentinelAI.git cd SentinelAI ``` ### 2. 后端设置 ``` cd backend npm install ``` 创建 `backend/.env`: ``` MONGO_URI=your_mongodb_connection_string JWT_SECRET=your_jwt_secret UPSTASH_REDIS_REST_URL=your_upstash_url UPSTASH_REDIS_REST_TOKEN=your_upstash_token ALERT_EMAIL=your_gmail@gmail.com ALERT_EMAIL_PASSWORD=your_gmail_app_password ADMIN_EMAIL=email_to_receive_alerts@gmail.com PORT=5000 ``` ``` npm start ``` ### 3. 前端设置 ``` cd frontend npm install npm start ``` 前端运行在 `http://localhost:3000`。注册一个账户,登录后仪表板即会自动加载。 ## 测试速率限制 项目包含一个负载测试脚本,用于模拟两种真实的攻击模式: ``` # 从 root 目录 npm install axios # 编辑 loadtest.js — 将 EMAIL 和 PASSWORD 设置为你的已注册账户 npm run loadtest ``` **阶段 1 — 突发攻击**:以 50ms 的延迟发送 20 个请求。滑动窗口(限制:5次/60秒)会在第 6 次请求时触发,并返回 429。你可以实时观察仪表板的数据变化。 **阶段 2 — 缓慢激增**:以 800ms 的延迟发送 15 个请求。展示了在完全封禁之前出现的可疑状态(逐渐逼近阈值)—— 这证明了滑动窗口不仅能捕获突发攻击,也能捕获缓慢攻击。 ## 安全规则(热配置) 所有阈值均存储在 MongoDB 中,无需重启服务器即可直接在仪表板中进行修改: | 规则 | 默认值 | 描述 | |---|---|---| | 滑动限制 | 5 | 每个滑动窗口的最大请求数 | | 滑动窗口 | 60s | 滑动窗口持续时间 | | 可疑阈值 | 60% | 触发“可疑”状态的限制百分比 | | 突发次数 | 3 | 触发警报前突发窗口内的请求数 | | 突发窗口 | 2s | 突发检测窗口 | | IP 突发次数 | 10 | IP 被自动封禁前的请求数 | | IP 封禁时长 | 60s | IP 保持封禁状态的时间 | | 用户每小时限制 | 500 | 每个用户每小时的最大请求数 | ## 部署到 Render ### Backend 1. 将你的代码推送到 GitHub 2. 访问 [render.com](https://render.com) → New → Web Service 3. 连接你的代码仓库 → 选择 `backend` 文件夹作为根目录 4. Build command:`npm install` 5. Start command:`node server.js` 6. 在 Environment 标签下添加 `.env` 中的所有环境变量 7. Deploy ### Frontend 1. 访问 Render → New → Static Site 2. 连接你的代码仓库 → 选择 `frontend` 文件夹作为根目录 3. Build command:`npm install && npm run build` 4. Publish directory:`build` 5. 添加环境变量:`REACT_APP_API_URL=https://your-backend-url.onrender.com` 6. Deploy ## 作者 Vartika Mishra — [GitHub](https://github.com/Vartika-Mishra13)
标签:API网关, AppImage, CISA项目, DOE合作, MERN栈, MITM代理, Redis, Web应用防火墙, 异常检测, 搜索引擎查询, 流量监控, 自定义脚本, 配置错误