derekslinz/logalytics
GitHub: derekslinz/logalytics
一个无需后端的实时流量分析仪表板,提供地理可视化、流量分类、扫描器检测与自动化 IP 屏蔽能力。
Stars: 1 | Forks: 0
# Logalytics
实时网页流量分析仪表板,具备地理可视化、流量分类和威胁检测功能。
 
[demo.webm](https://github.com/user-attachments/assets/9e235495-7077-47c1-bbcc-d96e253cc416)
## 功能
- **交互式地图** — 基于 Leaflet 的世界地图,按流量类型着色显示每个会话标记,带“BLOCKED”标签的被屏蔽国家覆盖层
- **流量分类** — 自动将流量归类为合法、来自云、托管、机器人和恶意流量
- **扫描器检测** — 模式匹配引擎标记对已知漏洞路径的请求(WordPress 探测、`.env` 收集、路径遍历、PHP Shell)
- **知名组织识别** — 通过 rDNS 和 ASN 识别访问者,将其分为云提供商与其他托管机构,并在弹出式模态框中显示位置数据和 Google 搜索链接
- **国家深入分析** — 点击国家报告模态框中的任意国家,展开完整的 IP 表格,包含流量类型、请求次数、最后出现时间戳和请求路径
- **屏蔽 IP 标识** — 在实时信息流、地图弹出框和国家报告中显示 `GEO-BLK` 和 `IP-BLK` 徽章,便于快速验证屏蔽情况
- **实时信息流** — 可滚动的流量表格,包含完整的日期+时间戳、指向 IPInfo.io 的热链接 IP 和屏蔽状态标识
- **回放功能** — 可调节速度的时间线滑块,用于重放流量模式
- **Top Scanned Paths** — 汇总并显示恶意行为者和机器人正在积极探测的服务器上的确切目录和文件
## 快速开始
```
# 克隆仓库
git clone https://github.com/your-username/logalytics.git
# 将仪表板文件移动到您的 Web 服务器文档根目录
sudo cp -r logalytics/html/* /var/www/html/logalytics/
```
然后在浏览器中导航到 `http://your-server/logalytics`。
仪表板期望在 `html/` 目录中有一个 `data.json` 文件。提供了一个 `data.sample.json` 用于参考。复制它以开始使用:
```
cp html/data.sample.json html/data.json
```
## 架构
```
html/
index.html # Dashboard shell, modals, Leaflet/Chart.js setup
app.js # All application logic
styles.css # Dark theme styles
countries.geojson # World borders for blocked country overlay
data.json # Session data (gitignored, you provide this)
data.sample.json # Example data with RFC 5737 documentation IPs
scripts/
block-scanner-ips.sh # Cron job: extract malicious IPs from data.json → ipset
setup-ipsets.sh # One-time: create ipsets + iptables rules
load-country-blocks.sh # Download country CIDR ranges from ipdeny.com → ipset
nginx-exploit-paths.conf # nginx snippet: 403 on exploit paths (WordPress, .env, etc.)
```
无后端依赖。仪表板是一个静态网站,仅读取一个 JSON 文件。
## 数据格式
仪表板消费一个包含三个顶级键的 `data.json` 文件:
### `sessions`(数组)
每个会话代表来自一个 IP 的请求簇:
```
{
"origin_ip": "203.0.113.42",
"edge_ip": "203.0.113.42",
"geo": {
"city": "Frankfurt am Main",
"country": "Germany",
"country_code": "DE",
"hostname": "example.host.com",
"asn": 24940,
"asn_name": "Hetzner Online GmbH",
"is_bot": false,
"is_verified_bot": false,
"is_cloud": false,
"is_hosting": true,
"lat": 50.1109,
"lon": 8.6821
},
"first_seen": 1711800000.0,
"last_seen": 1711800060.0,
"intent": "Passive Traffic",
"tags": ["crawler"],
"is_malicious": false,
"req_count": 15,
"req_rate": 0.25,
"is_spike": false,
"first_seen_iso": "2025-03-30T12:00:00",
"last_seen_iso": "2025-03-30T12:01:00",
"path_summary": ["/", "/robots.txt"]
}
```
### `notable`(数组)
通过 rDNS 或 ASN 识别的组织:
```
{
"label": "ASN: AS16509 (Amazon.com, Inc.) | Confidence: hosting provider only | Actor: unknown",
"ips": ["203.0.113.10", "203.0.113.11"],
"count": 2
}
```
标签前缀决定分类方式:
- `RDNS:` — 通过反向 DNS 识别(显示位置并链接到该 IP 的 Google 搜索)
- `ASN:` — 基于 ASN 的识别(归类为云提供商或其他托管机构,并链接到该 ASN 的 Google 搜索)
- `Verified Actor:` — 已确认的机器人身份(从显示中过滤)
### `summary`(对象)
```
{
"total_requests": 6324,
"unique_origin_ips": 630,
"updated_at": "2025-03-30T21:37:55",
"countries": {
"US": { "legit": 136, "bots": 88, "malicious": 61, "name": "United States" }
}
}
```
## 配置
所有配置位于文件顶部的 `app.js` 常量中:
| 常量 | 用途 |
|----------|---------|
| `BLOCKED_COUNTRIES` | 在地图上显示为屏蔽状态并在所有视图中标记的国家 ISO 代码 |
| `CLOUD_PROVIDERS` | 用于分组的 ASN 到提供商映射(Amazon、Google、Microsoft、Cloudflare、DigitalOcean、Akamai、OVH、Hetzner、Contabo、Alibaba) |
| `IGNORED_RDNS` | 从 notables 中排除的 rDNS 域名(例如 `censys-scanner.com`、`internet-measurement.com`) |
| `MALICIOUS_PATHS` | 无论来源如何都将会话标记为恶意的正则模式 |
| `TRAFFIC_COLORS` | 流量类型类别的配色方案 |
## 流量类型
| 类型 | 颜色 | 标准 |
|------|-------|----------|
| 合法 | 青色 `#00f2ff` | 无机器人/云/托管/恶意标志 |
| 云 | 紫色 `#a855f7` | `geo.is_cloud` 为真 |
| 托管 | 绿色 `#22c55e` | `geo.is_hosting` 为真 |
| 机器人 | 琥珀色 `#ffaa00` | `geo.is_bot` 为真 |
| 恶意 | 红色 `#f43f5e` | `is_malicious` 或命中扫描器路径模式 |
## 屏蔽 IP 标识
仪表板显示两种类型的屏蔽标识:
| 标识 | 含义 |
|-------|---------|
| `GEO-BLK` | IP 来自 `BLOCKED_COUNTRIES` 列表中的国家 |
| `IP-BLK` | IP 被单独标记为恶意(扫描器路径、已知攻击者) |
| `BLK` | 在国家详细报告中显示,用于屏蔽国家 |
这些标识出现在实时信息流、地图弹出框和国家详细表格中,用于快速验证防火墙规则(ipset、iptables、nginx)是否正常工作。
## 与 IP 屏蔽的集成
`scripts/` 目录包含在服务器层面实施屏蔽所需的一切。系统使用三层机制:
### 第一层:防火墙(ipset + iptables)
```
# 一次性设置:创建 ipset 并配置 iptables 规则
sudo ./scripts/setup-ipsets.sh
# 加载国家 CIDR 块(从 ipdeny.com 下载)
sudo ./scripts/load-country-blocks.sh ru by kz ir kp cn in br ph id vn ng
```
这创建了三个 ipset:
| ipset | 类型 | 用途 |
|-------|------|---------|
| `abusive_ips` | hash:ip | 单个恶意 IP 和来自屏蔽国家的 CDN 代理 IP |
| `scanner_nets` | hash:net | Censys、Shodan、internet-measurement CIDR 范围 |
| `blocked_countries` | hash:net | 国家级别的 CIDR 块 |
### 第二层:自动化 IP 提取(定时任务)
```
# 添加到 crontab(每 6 小时运行一次)
echo "0 */6 * * * $(pwd)/scripts/block-scanner-ips.sh" | sudo crontab -
```
`block-scanner-ips.sh` 读取 `data.json` 并执行以下操作:
- 屏蔽命中漏洞路径(WordPress、`.env`、`.git`、PHP Shell 等)的 IP
- 屏蔽来自地理屏蔽国家的 IP,**包括 CDN 代理流量**(Cloudflare 等)
- 将扫描器 rDNS 匹配项(Shodan、Censys 等)添加到 scanner_nets 集合
- **[可选]** 对未分类 IP 检查 AbuseIPDB 并自动报告恶意活动(需要 API 密钥)
- 将所有更改持久化到磁盘
编辑 `BLOCKED_COUNTRIES`、`ABUSE_SCORE_THRESHOLD`、`ABUSE_REPORT_THRESHOLD`、`MALICIOUS_PATHS` 和 `SCANNER_RDNS` 在脚本顶部(或通过环境变量覆盖)以自定义解析。
**AbuseIPDB 集成(可选):**
要启用自动威胁情报检查和报告,请在 [AbuseIPDB](https://www.abuseipdb.com/) 创建免费账户,并将 API 密钥保存到 `/etc/abuseipdb.key`:
```
echo "YOUR_API_KEY" | sudo tee /etc/abuseipdb.key
sudo chmod 600 /etc/abuseipdb.key
```
脚本将自动识别并使用它来屏蔽超过威胁阈值的未知 IP,同时报告已确认的恶意攻击者。
### 推荐的屏蔽实践
**典型恶意流量的前 10 个来源(建议加入 `BLOCKED_COUNTRIES`)**:
1. 中国(`CN`)
2. 俄罗斯(`RU`)
3. 巴西(`BR`)
4. 印度(`IN`)
5. 越南(`VN`)
6. 伊朗(`IR`)
7. 印度尼西亚(`ID`)
8. 菲律宾(`PH`)
9. 尼日利亚(`NG`)
10. 朝鲜(`KP`)
(注意:美国和各种欧洲国家也产生大量恶意流量,但由于来自那里的合法流量和搜索引擎机器人数量庞大,通常不进行全局屏蔽。)
**扫描器网段**:
我们强烈建议保持 `SCANNER_RDNS` 列表活跃。Shodan、Censys、internet-measurement 和 Shadowserver 等实体不断为开放端口和漏洞建立索引。屏蔽其网段可防止您的基础设施细节出现在公共漏洞数据库中,攻击者常利用这些信息进行侦察。
### 第三层:Web 服务器扫描器蜜罐
直接在 Web 服务器层拦截已知漏洞路径。
不返回快速的 `404 Not Found` 或 `403 Forbidden`,而是将这些配置作为 **蜜罐** 处理。返回伪造的 `200 OK - System Access Granted` 响应,其中包含虚拟的管理 HTML。这会恶意地遵守 Nikto、Z 和 DFind 等自动扫描器,迫使它们注册无尽的虚假漏洞,污染其侦察数据并浪费其时间。
**Nginx**:
```
# 添加到您的 Nginx 服务器块
include /path/to/scripts/nginx-exploit-paths.conf;
```
**Apache**:
```
# 添加到您的 Apache VirtualHost
Include /path/to/scripts/apache-exploit-paths.conf
```
(需要启用 `mod_rewrite`:`sudo a2enmod rewrite`)
## 安全部署示例
由于此仪表板会公开暴露内部 IP 数据和路径,**不应在未进行身份验证的情况下公开部署**。
### Nginx 示例(基础认证 + IP 白名单)
```
server {
listen 80;
server_name logs.yourdomain.com;
root /var/www/logalytics/html;
index index.html;
# Restrict to your office/VPN IPs
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
# Require password
auth_basic "Logalytics Admin";
auth_basic_user_file /etc/nginx/.htpasswd;
# Prevent direct access to raw data.json (optional, but UI needs it)
# The UI fetches via JS, so basic auth handles the protection.
# Enable GZIP for fast loading of data.json
gzip on;
gzip_types application/json;
}
```
### Apache 示例(基础认证)
```
ServerName logs.yourdomain.com
DocumentRoot /var/www/logalytics/html
AuthType Basic
AuthName "Logalytics Admin"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
# Or restrict by IP
# Require ip 192.168.1.0/24 10.0.0.0/8
```
## 生成 data.json
仪表板与数据源无关。您可以从任何 Web 服务器日志格式生成 `data.json`。典型流程:
1. 解析 nginx/Apache 访问日志
2. 使用 GeoIP 和 ASN 数据丰富 IP(MaxMind、ipinfo.io 等)
3. 按 IP 将请求聚类为会话
4. 分类意图(机器人检测、速率分析)
5. 通过 rDNS 和 ASN 查找识别知名组织
6. 输出上述 JSON 结构
### 恶意路径规则(`malicious_paths.txt`)
`scripts/log_analyze.py` 支持字面路径和正则规则:
- **字面路径**(标准化后的精确匹配):
- `/wp-login.php`
- **正则规则**(不区分大小写):
- `re:^/wp-.*`
- `re:wp-includes`
- `re:\\.env($|/)`
字面路径标准化规则(用于添加/移除):
- 去除首尾空白
- 折叠重复斜杠(`//` → `/`)
- 自动添加前导斜杠(`wp-login.php` → `/wp-login.php`)
- 保留尾随斜杠(`/admin/` 保持 `/admin/`)
可通过命令行添加规则:
- 添加字面路径(带确认提示):
- `python3 scripts/log_analyze.py --add-malicious-path /@vite/env`
- 添加正则规则:
- `python3 scripts/log_analyze.py --add-malicious-path '^/wp-.*' --regex`
- 示例:匹配任何包含 `wp-includes` 的路径:
- `python3 scripts/log_analyze.py --add-malicious-path 'wp-includes' --regex`
- 跳过确认(用于自动化):
- `python3 scripts/log_analyze.py --add-malicious-path '^/wp-.*' --regex --yes`
也可移除规则:
- 移除字面路径:
- `python3 scripts/log_analyze.py --remove-malicious-path /@vite/env`
- 移除正则规则:
- `python3 scripts/log_analyze.py --remove-malicious-path '^/wp-.*' --regex`
- 跳过确认:
- `python3 scripts/log_analyze.py --remove-malicious-path '^/wp-.*' --regex --yes`
### MaxMind GeoIP 增强
如果您使用 Python 自行构建解析器,我们推荐使用免费的 [GeoLite2 数据库](https://dev.maxmind.com/geoip/geolite2-free-geolocation-data)。需要 `geoip2` Python 库来读取这些数据库。
**依赖项**:
```
pip install geoip2
```
**示例实现**:
```
import geoip2.database
with geoip2.database.Reader('/usr/share/GeoIP/GeoLite2-City.mmdb') as city_db, \
geoip2.database.Reader('/usr/share/GeoIP/GeoLite2-ASN.mmdb') as asn_db:
city_response = city_db.city("203.0.113.42")
asn_response = asn_db.asn("203.0.113.42")
geo_data = {
"city": city_response.city.name,
"country": city_response.country.name,
"country_code": city_response.country.iso_code,
"asn": asn_response.autonomous_system_number,
"asn_name": asn_response.autonomous_system_organization,
"lat": city_response.location.latitude,
"lon": city_response.location.longitude
}
```
## 依赖项
全部从 CDN 加载(无需 `npm install`):
- [Leaflet](https://leafletjs.com/) v1.9.4 — 地图渲染
- [Chart.js](https://www.chartjs.org/) — 状态/类型/流量图表
- [chartjs-plugin-datalabels](https://chartjs-plugin-datalabels.netlify.app/) — 图表标签覆盖
- [Lucide Icons](https://lucide.dev/) — UI 图标
- [Inter](https://rsms.me/inter/) — 字体
## 许可证
MIT
标签:ASN 识别, CMS安全, .env 探测, HTML, IP 信息查询, IP 威胁阻断, JavaScript, Leaflet, rDNS 识别, SEO 流量分析, Web 监控, WordPress 探测, 云服务商识别, 交互式表格, 前端可视化, 国家封堵, 地图可视化, 地理可视化, 多模态安全, 威胁情报, 实时流量分析, 开发者工具, 恶意流量检测, 扫描器检测, 数据仪表盘, 数据可视化, 时间线滑块, 流量分类, 流量回放, 自定义脚本, 路径遍历检测, 黑名单标记