项目概览与功能导航
MyIP 是可自托管的 IP 与网络诊断工具箱,将多来源 IP 查询、隐私泄漏检测、网络测试、基础设施查询和结果分享集中在一个 Web 应用中。本页提供功能选择、运行架构和开发入口的整体地图。
目的与范围
本页适合首次使用、自托管或参与开发的读者,回答三个问题:应该选择哪个工具、请求由哪一层处理、出现问题应从哪里排查。
覆盖范围包括项目公开功能、前后端服务分工、已核实的公共请求处理链、关键运行配置及构建测试入口。各工具的算法、第三方 API 协议、离线数据库更新机制和报告存储实现不在这里展开;对应的操作说明见知识库,部署与扩展见开发者指南。运行时未提供其他 Wiki 目录的确切路径,因此本页不虚构同级页面链接。
证据范围:功能清单来自项目 README.md,架构和公共行为来自实际服务入口。未读取的功能模块不被视为已经完成实现级验证。
概述
项目定位
MyIP 不仅显示一个公网 IP,而是从不同观察角度诊断网络:
- 身份视角:多来源 IPv4/IPv6、地理位置、ASN、组织和浏览器指纹。
- 隐私视角:WebRTC 暴露的地址、DNS 解析出口及个人安全检查项。
- 路径与可达性视角:站点连通性、下载上传性能、全球探针延迟、MTR 和代理规则。
- 基础设施视角:DNS、Whois、MAC 厂商、ASN 上游拓扑、前缀与服务状态。
- 结果交付视角:只读分享链接、Markdown 和 JSON 诊断报告。
这些能力适合搭配使用,但不应混淆其观测位置。例如,项目说明将全球延迟和 MTR 定义为来自分布式探针的测量,而不是直接把用户本机作为所有测试的发起点。
来源:README.md。
技术基础
当前包元数据版本为 7.7.0,采用 ES modules;包管理器声明为 pnpm@12.4.2,Node.js 要求为 ^24.15.0 || >=26.0.0。依赖包含 Vue、Vue Router、Pinia、Vue I18n、Vite、Express、Pino 和 Sentry。这里的版本为仓库声明,不代表本页执行过安装或确认了线上运行版本。
来源:package.json。
功能导航
下表根据项目公开功能说明整理;“下一步”是推荐诊断顺序,不代表代码自动串联执行这些工具。
| 想解决的问题 | 推荐功能 | 结果与下一步 |
|---|---|---|
| 当前公网出口是什么,IPv4 与 IPv6 是否不同 | IP Cards | 对比多个来源的 IP、国家、地区、城市、ASN、组织和时区;必要时查询指定 IP |
| 某个 IP 属于谁 | Query IP、Whois Search | 查询地址信息;需要网络归属细节时进入 ASN 功能 |
| 出口是否发生过变化 | IP History | 按地址类型与国家过滤浏览器本地记录 |
| VPN 或代理是否仍暴露身份线索 | WebRTC Detection、DNS Leak Test、Browser Fingerprint | 分别检查 WebRTC 地址、DNS 解析端点和浏览器可识别性 |
| 某些网站打不开 | Connectivity Check、DNS Resolver | 先看可达性,再比较不同解析器的结果 |
| 网络慢在哪里 | Speed Test、Global Latency Test、MTR Test | 分别观察吞吐与延迟、全球探针延迟、逐跳路径 |
| 代理规则是否按预期分流 | Proxy Rule Test | 检查代理软件规则;需要按客户端设置对应测试规则 |
| 某个网站在哪些地区受阻 | Censorship Check | 查看全球阻断情况及方式 |
| 查询域名、设备或网段属性 | DNS Resolver、Whois Search、MAC Lookup、IP Calculator | 域名解析、注册信息、MAC 厂商识别、子网与地址表示计算 |
| 查看自治系统结构 | ASN Info & Upstream Topology、ASN Profile | 从 IP 卡片进入 ASN 信息,进一步查看前缀、RPKI、上下游、对等网络、交换中心与数据中心 |
| 区分自身网络故障与服务故障 | Service Status、Earth Online | 查看官方状态页汇总与全球互联网中断事件 |
| 保存并交给他人分析 | Shareable Reports | 输出自动过期的只读链接、适合 AI 分析的 Markdown 或 JSON |
| 持续改善安全习惯 | Security Checklist | 12 个领域、258 个检查项,进度保存在浏览器 |
补充体验包括深色模式、PWA 安装、快捷键和 6 种界面语言;项目说明建议按 ? 查看快捷键。连通性工具支持最多 60 个自选站点、多轮最低延迟结果和分类导入列表。
来源:README.md。
运行架构
pnpm start 通过 concurrently 启动两个 Node.js 服务:前端服务负责构建产物与 API 反向代理,后端服务负责 API 公共处理和功能模块集成。前端服务不是 Vue 开发服务器;开发模式另由 Vite 提供。
Sources: package.json、frontend-server.js、backend-server.js、backend-server.js。
图中的 api/* 虚线仅表示已经验证的模块导入,不表示所有导入都以同样方式、同一路由暴露。此次读取没有覆盖后端完整路由表,也没有验证各浏览器工具是否直接调用外部服务,因此不能把全部功能都归为后端代理请求。
前端服务的三个职责
- API 代理优先:先挂载
/api,目标是http://localhost:${backEndPort}/api,并开启changeOrigin。 - 静态资源服务:随后通过
express.static提供dist,按资源类别设置缓存头。 - SPA 深链接回退:最后为符合条件的页面导航返回
index.html,让 Vue Router 解析路径。注释给出的例子是/tools/whois。
这一顺序避免 SPA 回退覆盖正常 API 和资源请求。尤其是末段含扩展名的路径不会被当作页面返回 HTML,防止缺失的 JS/CSS 文件变成难以定位的解析错误。
后端公共入口
后端入口导入多家 IP 信息处理器,以及 DNS、Whois、ASN、服务状态、报告等模块;公共治理集中在功能路由之前:可选 HTTP 日志、可选限流与延迟、JSON 解析、API 缓存默认值和 requireReferer。
入口还为 MaxMind、AS 关系与组织数据、OUI 数据、服务状态分别创建就绪检查中间件。源码注释说明,本地数据启动下载期间会返回 503;本页不推断这些中间件绑定到哪些完整路由。
来源:backend-server.js、backend-server.js。
核心请求流程
下图只展示已读取的 API 公共处理链,不包含各功能处理器内部的上游调用、缓存或数据库行为。
Sources: frontend-server.js、backend-server.js、backend-server.js。
关键顺序及其意义:
- 日志挂在限流前,因此启用后也能记录 429。
- 限流器的窗口为 20 分钟,触发后返回 HTTP 429 与
Too Many RequestsJSON 消息。 - 延迟器的窗口为 1 小时,超过阈值后按每次额外请求 400ms 增加延迟,上限 5000ms;它不是重试机制。
- JSON 请求体上限提高到
500kb,注释说明这是为共享诊断报告预留解析空间,报告处理器仍有自己的更严格校验。 /api到达缓存中间件后默认设置no-store;源码说明需要边缘缓存的路由应显式使用cacheable(maxAge)。- 不能据此声称所有错误响应都有
no-store:在更早的限流或 JSON 解析阶段结束的请求可能尚未经过该中间件。
使用与源码示例
1. 快速运行官方镜像
以下命令直接摘自项目说明,发布前端端口 18966:
docker run -d -p 18966:18966 --name myip --restart always jason5ng32/myip:latestSource: README.md。
这只是最小启动方式,不代表自定义域名和 MaxMind 查询已经配置完成。项目说明明确要求真实域名部署设置 ALLOWED_DOMAINS,并为 MaxMind 配置凭据。
2. 从源码安装并构建
在已获取仓库且 Node.js 版本符合包元数据要求的前提下,项目说明给出:
npm install -g pnpm
pnpm install && pnpm run buildSource: README.md。
构建后使用项目提供的启动命令:
pnpm startSource: README.md。
不要仅依据 README 中“安装 Node.js”的概括选择运行时;实际支持范围以 package.json 的 engines 为准。
3. 理解前后端连接点
1frontendApp.use('/api', createProxyMiddleware({
2 target: `http://localhost:${backEndPort}/api`,
3 changeOrigin: true
4}));Source: frontend-server.js。
这是生产静态服务连接后端的直接证据:页面入口和 API 入口可以共用前端服务端口,内部 API 流量再转发到后端配置端口。开发模式的 Vite 代理配置未在本页核实。
4. 理解深链接的边界
1frontendApp.use((req, res, next) => {
2 if (req.method !== 'GET' || !req.accepts('html')) return next();
3 if (req.path.split('/').pop().includes('.')) return next();
4 res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
5 res.sendFile(path.join(distDir, 'index.html'));
6});Source: frontend-server.js。
这段代码解释了为什么客户端页面可以直接打开,也说明了回退限制:非 GET、不能接受 HTML,或者路径最后一段包含点号的请求均继续交给后续处理,而不是强制返回首页。
配置导航
下表只列概览层面重要且在已读取材料中有依据的配置。未确认的默认值明确标记,不从部署示例反推。
| 配置项 | 类型/读取方式 | 默认值 | 作用与注意事项 |
|---|---|---|---|
FRONTEND_PORT | 环境变量字符串,经 parseInt(..., 10) 读取 | 18966 | 前端静态服务监听端口 |
BACKEND_PORT | 环境变量字符串,经 parseInt(..., 10) 读取 | 11966 | 后端端口变量,同时供前端生成本地代理目标 |
LOG_HTTP | 字符串,严格比较 === 'true' | 未设置时关闭 | 启用 /api HTTP 日志 |
SECURITY_RATE_LIMIT | 字符串转整数 | 0 | 非零时挂载限流器;每 20 分钟窗口的请求阈值 |
SECURITY_DELAY_AFTER | 字符串转整数 | 0 | 非零时挂载延迟器;1 小时窗口内开始延迟的阈值 |
SECURITY_BLACKLIST_LOG_FILE_PATH | 字符串 | 空字符串 | 可选限流记录文件;为空时不写文件,警告日志仍记录 |
ALLOWED_DOMAINS | 环境变量,实际解析未在本页核实 | 未核实 | README 指出真实域名部署必须配置,否则非 localhost 域名请求返回 403 |
MAXMIND_ACCOUNT_ID | 凭据环境变量 | 未核实 | MaxMind GeoLite2 账户信息 |
MAXMIND_LICENSE_KEY | 凭据环境变量 | 未核实 | MaxMind GeoLite2 授权密钥;README 指出缺少凭据会使 MaxMind 来源返回 503 |
DATASET_AUTO_UPDATE | 环境变量,实际解析未在本页核实 | 未核实;README 示例为 true | 数据集自动更新配置入口,具体策略见专项部署文档 |
来源:frontend-server.js、backend-server.js、backend-server.js、README.md。
这些端口和安全阈值采用直接整数解析;已读取入口未显示数值范围验证。不要把负数、非数字字符串或异常端口当作受支持配置。
接口与开发入口
HTTP 边界
本页确认 /api 是前端代理与后端公共中间件的挂载前缀,但不提供未核实的工具端点签名、参数或返回结构。后端导入了 ipinfoHandler、maxmindHandler、dnsResolver、getWhois、asnProfileHandler 和报告处理器等;导入名不等同于 HTTP 路由契约。
项目脚本
| 脚本 | 已核实行为 | 适用场景 |
|---|---|---|
dev | 并行运行 Vite 与带 Sentry 导入的 nodemon 后端 | 本地开发 |
build | 执行 vite build | 生成生产前端产物 |
postbuild | 若清理索引缓存的脚本存在,则启动该脚本并传递退出状态 | 构建后的缓存清理钩子;内部行为未核实 |
start | 并行启动前后端 Node.js 服务 | 运行已构建应用 |
start-backend / start-frontend | 分别启动后端与静态前端服务 | 分开管理进程 |
test | 使用 Node.js 测试运行器执行 tests/*.test.js,并导入测试初始化模块 | 自动化测试入口 |
check | 先测试,成功后再构建 | 基础质量检查 |
dns-check / fetch-favicons | 分别调用 DNS 检查与图标获取脚本 | 维护工具数据与资源 |
i18n-status / i18n-new / i18n-sync | 分别调用翻译状态和语言包脚手架工具 | 国际化维护 |
来源:package.json。
本页没有运行测试,也未读取测试用例,因此不声明覆盖率、测试通过状态或特定工具的边界保证。
数据与状态边界
不能把 MyIP 整体描述为“所有数据仅保存在浏览器”或“全部请求都不落盘”。目前可确认的边界是:
- 项目说明将 IP History 明确描述为仅在浏览器保存,将 Security Checklist 进度描述为浏览器保存。
- IP Calculator 的地址和子网计算在本地完成,这是项目说明中的功能约定。
- 后端存在 MaxMind、AS 关系、AS 组织、OUI 与服务状态的就绪检查入口,说明部分能力依赖本地数据或预加载状态。
- 可选限流记录文件会存储 IP、计数和首次记录时间。
- 分享报告的存储介质、过期清理、权限模型,以及其他用户数据持久化细节未在已读取实现中确认,不在概览中假定。
来源:README.md、backend-server.js、backend-server.js。
故障模式、边界与并发
| 现象 | 已验证原因或边界 | 排查方向 |
|---|---|---|
| 页面可访问,API 在真实域名下返回 403 | README 明确提示缺少 ALLOWED_DOMAINS 的结果;入口统一挂载 requireReferer | 先检查域名允许列表,再检查反向代理配置 |
| MaxMind 来源返回 503 | README 指出需要 MaxMind 凭据;入口对本地数据创建启动就绪门禁 | 区分凭据缺失与启动期间数据尚未就绪,不直接归因于整个服务崩溃 |
| API 返回 429 | 启用限流后超过窗口阈值 | 核对 SECURITY_RATE_LIMIT 和请求来源 |
| API 响应逐渐变慢 | 启用延迟器后,超过阈值会附加延迟,最高 5 秒 | 检查 SECURITY_DELAY_AFTER,再判断上游是否缓慢 |
| 请求体在功能处理器前被拒绝 | 全局 JSON 解析上限为 500kb;报告还有更紧的自身限制 | 区分全局解析限制和报告校验限制 |
| 深链接能打开但旧资源加载失败 | SPA 回退刻意排除文件扩展名路径 | 检查构建产物与缓存,而不是把缺失资源统一重写成首页 |
来源:README.md、backend-server.js、frontend-server.js。
限流日志不是并发计费账本
logLimitedIP(ip) 使用异步读文件、修改全文、再写回的方式更新记录;已读取函数没有显示锁或原子更新。由这一控制流可推断,并发更新存在覆盖风险,因此应把它当作可选运维记录,而不是精确计数账本。它保留已有记录的首次时间戳,读写失败记录错误;未在这一函数中看到重试。
限流器只在 current === limit + 1 时记录一次警告及可选文件,避免每一个已被拒绝的请求都产生同样的日志。全局限流跳过 /monitoring;延迟器跳过 /monitoring 和 /maxmind。这些豁免不等于相关端点完全没有保护,监控路由自己的限流实现未在本页读取。
代理与客户端地址
入口设置 trust proxy 为 1。限流记录使用的 getClientIp(req) 按 cf-connecting-ip、x-forwarded-for 第一项、cf-connecting-ipv6、req.ip 的顺序取值。该函数在已读取代码中用于限流日志,不能据此认定它也是限流器的键生成函数。自托管时应核对代理拓扑和转发头来源,避免把不可信头直接当作可信身份信息。
来源:backend-server.js、backend-server.js。
性能与运维要点
静态缓存分层
| 资源类别 | 前端服务设置的策略 |
|---|---|
assets/、fonts/ | 365 天,immutable |
favicons/ | 30 天 |
| 其他匹配图片扩展名的资源 | 7 天 |
HTML、manifest.webmanifest、指定 SEO 文本/XML 文件 | 浏览器 max-age=0,共享缓存 s-maxage=86400,must-revalidate |
| 其他静态文件 | 1 小时 |
| SPA 路由回退返回的首页 | no-store, no-cache, must-revalidate |
长缓存可以减少重复传输,但同时要求资源发布策略与文件名一致。源码特别说明,未带内容哈希的图片修改后需要改名;页面入口和深链接的缓存策略也不相同。项目配置提供了构建后清理索引缓存的钩子,但本页未验证 CDN 配置及清理脚本内部逻辑。
建议的故障定位顺序
- 先分层:页面/资源故障检查静态服务;API 故障检查后端;单一数据来源故障继续定位该功能。
- 再看公共门禁:域名允许列表、限流、附加延迟、请求体大小和离线数据就绪状态。
- 需要时打开请求日志:
LOG_HTTP=true时,5xx 或请求错误为error,4xx 为warn,其余为info。 - 最后深入功能模块:上游超时、缓存命中、重试和完整降级策略必须在各处理器中确认,不能由公共入口推断。
来源:backend-server.js、backend-server.js。
扩展方向与阅读路径
- 增加语言:项目说明采用语言包加注册项的方式,并接受部分翻译;包脚本提供状态检查、新建和同步入口。具体注册实现不在本页验证范围内。
- 维护网络测试数据:项目说明列出增加 DNS 解析器和分类站点列表作为适合贡献者的任务;应继续核对相应数据结构和测试,而不是只新增显示文本。
- 扩展后端能力:入口体现了“功能处理器导入 + 公共中间件”的组织方式。新增功能时,应专门检查输入守卫、本地数据依赖、缓存策略与上游访问,不能只依据导入语句推定集成完成。
- 提交前检查:优先使用已有
check脚本执行测试后构建;具体贡献流程以项目贡献文档为准,README 提醒 PR 面向dev分支。
来源:README.md、package.json、backend-server.js。