Skip to content
logdnsPublic

About

多数据源 IP 信息查询系统 - Multi-source IP Query System with Leaflet Map

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

🌐 IP 信息查询系统 / IP Query System

多数据源聚合的 IP 地理位置、网络信息、安全检测查询系统。支持 AbuseIPDB、iplocate.io、ip2location.io、ipdata.co 四数据源实时对比分析,内嵌 OpenStreetMap 地图定位。

A multi-source IP geolocation, network info, and security detection system with AbuseIPDB, iplocate.io, ip2location.io, and ipdata.co comparison plus embedded OpenStreetMap positioning.

✨ 功能特性 / Features

前台查询 / Frontend

  • 🔍 IP 信息查询 — 输入任意 IPv4/IPv6 地址,聚合多源数据
  • 📊 多源对比 — 四数据源并排对比,差异高亮
  • 🛡️ 安全检测 — VPN / 代理 / Tor / 威胁检测,AbuseIPDB 滥用评分
  • 🗺️ 地图定位 — Leaflet + OpenStreetMap 嵌入式地图,深色/浅色主题自动切换 Tile
  • 📍 街道地址 — Nominatim 反向地理编码,精确到街道级别
  • 🌐 多语言 — 支持 English、简体中文、繁體中文、日本語
  • 💻 浏览器标识 — 自动检测并展示访客浏览器、操作系统、设备类型
  • 🎨 主题切换 — 深色 / 浅色主题一键切换
  • 📱 响应式 — 完美适配桌面端和移动端

管理后台 / Admin (/admin)

  • 🔐 密码认证 — Token 鉴权,24h 自动过期
  • 📝 SEO 设置 — 按语言配置网站标题、描述、关键词
  • 🔑 API Key 管理 — 在线管理四个数据源的多 Key 随机轮询
  • 🔗 接口地址配置 — 自定义各数据源 API 端点地址,方便接入代理或新数据源
  • 🗺️ 地图设置 — 配置 Nominatim 联系邮箱
  • 🔒 安全设置 — 修改管理密码
  • 📢 广告位管理 — Head、顶部、搜索区、结果区、底部和左右对联七个位置,支持重复脚本独立实例、HTML / 纯 JS 和旧式脚本兼容加载
  • ⚡ 实时生效 — 所有设置修改即时生效,无需重启服务

广告位配置与验证

进入 /admin → 广告,勾选对应广告位,粘贴代码并保存,然后刷新前台。

广告位 前台位置 / 加载时机
Head 服务端注入 <head>,适合平台初始化、统计或验证;本身不是可见横幅
顶部 标题下方,首页加载
搜索区 搜索框下方,首页加载
结果区 查询结果顶部,查询成功、结果容器可见后才执行;重复查询不重复初始化
底部 页脚上方,首页加载
左侧对联 宽屏桌面左侧固定,宽度至少 1500px 时加载,可单独关闭
右侧对联 宽屏桌面右侧固定,宽度至少 1500px 时加载,可单独关闭

代码类型:含 <script> 标签的完整代码、文字、图片或 iframe 选 HTML / 脚本标签;不带 <script> 标签的 JavaScript 选 纯 JavaScript。旧配置默认按 HTML 加载,保留原有启用状态和代码。

加载方式:

  • 自动:通常在主页面执行;代码中直接出现 document.write / document.writeln,或多个启用广告位使用相同普通 HTML/JS 脚本时,使用各自独立的 iframe。所有广告位(包括尚未显示的结果位和窄屏隐藏的侧栏位)在执行前统一识别重复代码,避免重复 ID、全局变量和单次初始化标记只给顶部填充广告。AdSense / GPT 识别为主页面 SDK,保持页面内执行;识别是启发式的,其他依赖主页面的 SDK 请显式选择页面内。
  • 页面内:适合 AdSense 等需要主页面 DOM 的现代 SDK;普通外部脚本加载完后再执行后续初始化,显式 async 保留异步语义。显式选择会覆盖自动隔离;同一固定容器 ID 的普通广告代码不适合在多个位置同时用页面内模式。现代平台仍需按平台要求配置不同广告单元/容器,不能保证重复同一单元都获得填充。
  • iframe 兼容:同一代码可在各广告位分别解析和初始化,支持自动调整高度。脚本型旧式加载器恢复解析器顺序以支持 document.write;带容器的原生异步组件保留 async,避免脚本在其后面的容器解析前运行。不同内容但共享全局状态的脚本,或无法自动识别的外部旧脚本,请手动选择此模式。要求直接操作主页面 DOM 的 SDK 不适合此模式。

左右对联:分别保存代码、启用状态和加载方式;升级旧配置后默认关闭,不影响已有四个可见广告位。侧栏位宽 160–280px,建议使用 160×600 或自适应竖幅素材,不要直接粘贴固定宽度的大横幅。视口小于 1500px 时不执行侧栏脚本;变宽后首次初始化。关闭只影响当前页面的一侧,刷新后恢复。侧栏超出可视高度时可滚动,始终留在主内容两边。

所有广告代码具有脚本执行权限,iframe 模式是兼容隔离而不是安全沙箱;只允许可信管理员配置可信平台代码,不要粘贴未知来源脚本。

排查不显示:

  1. 确认广告位已启用、代码非空,后台保存成功;结果区必须先完成一次查询。
  2. 浏览器 Network 检查 /api/ads 的启用状态、代码类型和加载方式;Head 从首页 HTML 检查。广告接口与首页禁止缓存,静态资源使用版本参数规避旧缓存。
  3. 检查广告拦截插件、脚本请求失败、HTTPS 页面中的 HTTP 资源、平台域名审核或无广告填充。这些情况无法仅靠网站代码解决。
  4. 查看浏览器控制台 [Ads:广告位ID] 提示,以及容器 data-ad-status / data-ad-error。pending 表示等待结果区显示或侧栏有足够空间;loaded 仅表示配置/脚本加载完成,不代表平台一定返回了广告。data-ad-mode 和 data-ad-frame-reason 可区分页面内、显式 iframe、document.write 或重复代码隔离。

回归测试(开发测试环境需要 Node.js 20+;测试使用临时目录,不修改实际 data/settings.json):

npm install
npm test
# macOS 默认可复用已安装的 Google Chrome;其他环境先安装测试浏览器
npx playwright install chromium
npm run test:browser

可通过 PLAYWRIGHT_CHROMIUM_EXECUTABLE 指定 Chromium / Chrome 可执行文件。测试覆盖配置保存与旧配置迁移、权限及格式校验、HTML / JS / iframe、重复代码与全局变量隔离、旧式加载器和原生异步组件、结果区延迟加载、左右对联的宽屏布局与独立关闭、错误隔离和后台到前台的完整操作。

📦 技术栈 / Tech Stack

组件 Component 技术 Technology
后端 Backend Node.js + Express
前端 Frontend 原生 HTML/CSS/JS
数据源 Sources AbuseIPDB / iplocate.io / ip2location.io / ipdata.co
地图 Map Leaflet + OpenStreetMap + CARTO Tiles
地理编码 Geocoding OpenStreetMap Nominatim
CDN cdn.jsdelivr.net (Inter font, Leaflet)
配置 Config JSON 文件持久化

🚀 快速开始 / Quick Start

1. 克隆项目

git clone https://github.com/logdns/ip-query.git
cd ip-query

2. 安装依赖

npm install

3. 配置环境变量

cp .env.example .env

编辑 .env 文件,填入你的 API Key:

# 服务端口
PORT=3008

# AbuseIPDB API Keys (支持多个,逗号分隔)
ABUSEIPDB_KEYS=your_key_1,your_key_2

# iplocate.io API Keys (多个 key 轮询使用,逗号分隔)
IPLOCATE_API_KEY=your_iplocate_key_1,your_iplocate_key_2

# ip2location.io API Keys (多个 key 轮询使用,逗号分隔;留空则使用免费额度)
IP2LOCATION_API_KEY=your_ip2location_key_1,your_ip2location_key_2

# ipdata.co API Keys (多个 key 轮询使用,逗号分隔)
IPDATA_API_KEYS=your_ipdata_key_1,your_ipdata_key_2

# 管理后台密码
ADMIN_PASSWORD=your_admin_password

# Nominatim 联系邮箱 (可选)
NOMINATIM_EMAIL=your-email@example.com

注意: 首次启动时,系统会自动从 .env 迁移配置到 data/settings.json。之后可通过管理后台在线修改,无需编辑文件。

4. 启动服务

# 开发模式
npm run dev

# 生产模式
npm start

服务器启动后访问:


🐧 宝塔面板部署指南 / BT Panel Deployment

第一步:环境准备

  1. 登录宝塔面板,进入 软件商店
  2. 安装 PM2 管理器(Node.js 进程管理)
  3. 安装 Nginx(如果尚未安装)
  4. 在 PM2 管理器中确认 Node.js 版本 >= 16

第二步:上传项目

方式一:Git 克隆(推荐)

cd /www/wwwroot
git clone https://github.com/logdns/ip-query.git
cd ip-query
npm install --production

方式二:宝塔文件管理器上传

  1. 打开宝塔 文件 管理器,进入 /www/wwwroot/
  2. 上传项目压缩包并解压到 /www/wwwroot/ip-query/
  3. 在终端执行 cd /www/wwwroot/ip-query && npm install --production

第三步:配置环境变量

cd /www/wwwroot/ip-query
cp .env.example .env

编辑 .env 文件,填入你的 API Key 和管理密码。

第四步:PM2 启动项目

方式一:宝塔 PM2 管理器界面

  1. 打开 PM2 管理器
  2. 点击 添加项目
  3. 填写信息:
    • 项目名称: ip-query
    • 启动文件: /www/wwwroot/ip-query/server.js
    • 运行目录: /www/wwwroot/ip-query
  4. 点击 提交

方式二:命令行

cd /www/wwwroot/ip-query
pm2 start server.js --name ip-query
pm2 save
pm2 startup

第五步:配置 Nginx 反向代理

  1. 在宝塔面板 网站 中添加站点,填写你的域名
  2. 点击 设置 → 反向代理 → 添加反向代理
  3. 填写:
    • 代理名称: ip-query
    • 目标 URL: http://127.0.0.1:3008
  4. 点击 提交

或者手动编辑 Nginx 配置

点击 设置 → 配置文件,在 server {} 块内添加:

# 获取真实 IP (重要!)
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

# 静态文件缓存
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
    root /www/wwwroot/ip-query/public;
    expires 7d;
    add_header Cache-Control "public, immutable";
}

# 反向代理到 Node.js
location / {
    proxy_pass http://127.0.0.1:3008;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_cache_bypass $http_upgrade;
    proxy_connect_timeout 60s;
    proxy_read_timeout 60s;
}

第六步:配置 SSL(可选但推荐)

  1. 在宝塔面板 网站 → 设置 → SSL
  2. 选择 Let's Encrypt 免费证书
  3. 点击 申请

第七步:验证部署

  • 访问 https://你的域名 查看前台
  • 访问 https://你的域名/admin 进入管理后台
  • 默认管理密码为 .env 中设置的 ADMIN_PASSWORD

常用运维命令

# 查看运行状态
pm2 status

# 查看日志
pm2 logs ip-query

# 重启
pm2 restart ip-query

# 停止
pm2 stop ip-query

# 更新代码后重启
cd /www/wwwroot/ip-query
git pull
npm install --production
pm2 restart ip-query

🔄 升级与数据迁移 / Upgrade & Data Migration

系统支持后台一键在线更新,也可手动更新。无论哪种方式,用户配置数据都会自动保留,无需手动迁移。

配置数据存放在哪里?

数据 存储位置 是否纳入 Git 更新时是否保留
API 密钥 / 管理密码 / SEO / 接口地址 data/settings.json ❌ 已被 .gitignore 忽略 ✅ 自动保留
环境变量(仅首次启动用于初始化) .env ❌ 已被 .gitignore 忽略 ✅ 自动保留
程序代码 各源码文件 ✅ 🔄 被新版本覆盖

核心机制:data/settings.json 与 .env 都在 .gitignore 中,git pull 永远不会覆盖它们。所有在管理后台修改的配置都持久化在 data/settings.json,因此升级是无损的。

方式一:后台在线更新(推荐,基于 GitHub Releases)

后台更新基于 GitHub Releases:只有维护者发布正式 Release 时才会提示更新,版本号语义化(如 v1.1.0),并附完整更新说明。

  1. 进入管理后台 → 在线更新 标签页
  2. 点击 检查更新,系统会调用 GitHub API 获取最新 Release,对比当前版本,展示版本号、发布时间与更新说明
  3. 若有新版本,点击 更新到 vX.Y.Z,系统会:
    • git fetch --tags 后强制对齐(git reset --hard)到该 Release 对应的 tag;本地代码改动会被覆盖,但 data/settings.json、.env 已被 gitignore,用户配置不受影响
    • 自动 pm2 restart 重启进程使新代码生效
    • 轮询健康检查,服务恢复后自动刷新页面

若未运行在 PM2 下,后台会提示需手动重启进程(前端文件已生效,刷新即可)。 私有仓库可在 .env 中配置 GITHUB_TOKEN 以访问 Release API。

维护者:如何发布新版本

本项目直接运行 Node.js 和静态前端,没有编译或打包依赖。发布构建是从已审核的固定 tag生成源码归档,不从脏工作区复制文件。重复广告与左右对联的升级说明见 v1.1.13 发布记录;前次广告对接修复与部分审计记录保留在 v1.1.12 发布记录。

# 1. 提交并推送代码到 main
git push origin main

# 2. 打 tag 并发布 Release (需安装 gh CLI)
gh release create v1.1.0 --title "v1.1.0" --notes "## 更新内容
- 新增 XXX 功能
- 修复 YYY 问题"

发布后,所有部署方在后台「检查更新」即可看到 v1.1.0 及其更新说明。

正式发布时,先更新 package.json / package-lock.json 版本和静态资源缓存参数,完成测试与审查,提交所有新增运行模块;为该提交创建未使用的 annotated tag,并核对远端没有漂移。将分支和 tag 一并推送,Release 必须引用该 tag。

源码附件采用单一版本目录前缀,提供 .tar.gz、.zip 和 SHA256SUMS。归档必须与 tag 的 Git 文件树逐文件一致,不包含 .env、实际 data/settings.json、node_modules 或测试输出;.env.example 仅允许经审查的示例占位值。发布后下载附件,核对本地构建摘要与归档内容,并验证远端分支和 tag 都指向已审核提交。

方式二:命令行手动更新

cd /www/wwwroot/ip-query
git fetch --tags                       # 拉取最新 tag(不会动 data/settings.json)
git checkout v1.1.0                    # 切换到目标版本
npm install --production               # 如有新依赖
pm2 restart ip-query                   # 重启使后端代码生效

新增配置项如何自动迁移?

lib/settings.js 在读取时使用 deepMerge 将已存在的 settings.json 与新版默认配置合并:

  • 新版本新增的配置字段 → 自动补上默认值
  • 你已有的配置值 → 原样保留,不被覆盖

因此从旧版本升级后,无需手动编辑 settings.json,新功能所需的配置项会自动出现。

从旧版本首次迁移(手动备份建议)

升级生产环境前,建议先备份配置(一行命令即可):

cp data/settings.json data/settings.json.bak    # 备份当前配置
# 如更新后出现异常,可随时回滚:
#   cp data/settings.json.bak data/settings.json && pm2 restart ip-query

若需回退到某个旧版本代码:

git log --oneline                 # 查看历史版本
git checkout <commit-hash>        # 切到指定版本(data/settings.json 不受影响)
pm2 restart ip-query

📂 项目结构 / Project Structure

ip-query/
├── server.js              # Express 后端服务
├── package.json           # 项目依赖
├── .env.example           # 环境变量模板
├── nginx.conf             # Nginx 配置参考
├── lib/
│   ├── settings.js        # 设置管理模块
│   └── ads.js             # 广告配置校验与 Head 代码包装
├── test/                  # 临时配置的接口和浏览器回归测试
├── docs/releases/         # 版本发布记录与验证限制
├── data/
│   └── settings.json      # 持久化设置 (自动生成)
└── public/
    ├── index.html          # 前台页面 (中英双语)
    ├── admin.html          # 管理后台页面
    ├── css/
    │   ├── style.css       # 前台样式
    │   └── admin.css       # 管理后台样式
    └── js/
        ├── app.js          # 前台逻辑 (含 Leaflet 地图)
        ├── ads.js          # 独立广告加载、执行与兼容模式
        └── admin.js        # 管理后台逻辑

🔌 API 接口 / API Endpoints

路由 Route 方法 Method 说明 Description 认证 Auth
/api/myip GET 获取访客公网 IP / Get visitor IP 否 No
/api/useragent GET 获取浏览器标识 / Get browser info 否 No
/api/query?ip=x.x.x.x GET 聚合查询 IP 信息 / Query IP info 否 No
/api/geocode?lat=xx&lon=xx GET 反向地理编码 / Reverse geocode 否 No
/api/seo GET 获取 SEO 配置 / Get SEO config 否 No
/api/admin/login POST 管理员登录 / Admin login 否 No
/api/admin/settings GET/PUT 获取/更新设置 / Get/Update settings ✅
/api/admin/logout POST 登出 / Logout ✅

🔑 数据源说明 / Data Sources

AbuseIPDB

iplocate.io

  • 需要 API Key(免费注册 / Free registration)
  • 提供详细信息:地理位置、ASN、VPN/Proxy/Tor/威胁检测、公司信息、托管商信息
  • 支持多 Key 随机轮询
  • API 格式: GET https://iplocate.io/api/lookup/{ip}?apikey=YOUR_KEY
  • 文档: https://www.iplocate.io/docs

ip2location.io

  • 可配置 API Key;留空时使用官方免费额度
  • 提供地理位置、ASN、代理/VPN/数据中心与欺诈评分信息
  • 支持多 Key 随机轮询
  • API 格式: GET https://api.ip2location.io/?key=YOUR_KEY&ip={ip}
  • 文档: https://www.ip2location.io/ip2location-documentation

ipdata.co

  • 需要 API Key
  • 提供地理位置、ASN、公司、时区与威胁检测信息
  • 支持多 Key 随机轮询
  • API 格式: GET https://api.ipdata.co/{ip}?api-key=YOUR_KEY
  • 文档: https://docs.ipdata.co/docs/getting-started

OpenStreetMap Nominatim

📄 License

MIT © logdns

About

多数据源 IP 信息查询系统 - Multi-source IP Query System with Leaflet Map

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages