[{"content":"写在前面:有的人会觉得我与以往的文气大不相同了，或者更多没见过我认真写的文章，写这篇文章有两个目的，一个是寻点乐子，但绝不意味着我轻视这个问题，另一个问题是我想尝试下煽动性的文章，试试手感，可惜我还是以理性的议论文，想象作文，演讲见长，不管怎么说，我会再写一篇负责任的文章，这篇文章就和他的作者以及他的笔，值得当做笑话看吧\n你的命，只值30块？\n一份完整身份信息，20元。你的实时定位，1800元。你五年开房记录，12800元——而你，还在以为自己的隐私很值钱？\n别天真了。\n在黑市上，你连瓶水都不如。一瓶农夫山泉卖2块，你的“姓名+手机号”打包批发，最低只要3分钱。3分钱，连颗糖都买不到，却能买到你的电话号码、你的真实姓名、你每天被骚扰电话轰炸的通行证。\n这不是危言耸听，这是2026年互联网的残酷真相。我手里这份刚从暗网流出的“2025-2026年非法数据报价单”，每一行都在嘲笑我们的无知——你的隐私正在被按斤甩卖，而你，还在为免密支付沾沾自喜。\n批发区：你被当白菜卖了，还帮人数钱\n先看看“批发市场”。这里的规则只有一个：量大从优，薄利多销。你的信息不是“个”卖，是“万条”卖。十万条起批，单价低到令人发指。\n· 姓名+手机号：0.03 - 0.4元/条。按万条打包，平均每条几分钱。你每天收到的骚扰电话、推销短信、诈骗链接，源头就在这——一个诈骗分子花30块钱买你1000条信息，骗到一个人就回本，剩下的999个全是纯利润。 · 快递外卖信息：0.3 - 0.5元/条。一千条起批。你撕碎面单、涂黑地址，以为万无一失？可你那单麻辣烫的配送记录，正以3毛钱的价格在QQ群里被叫卖。买家拿到后，知道你几点下班、家里几口人、甚至知道你备注的“放门口鞋柜”——下一回敲你家门的，可能不是快递员，是催债的。 · 学生数据：0.5 - 10+元/条。价格看“含金量”：只有姓名班级的五毛，加上家长电话的两块，再附上家庭住址和身份证号的直奔十块。2026年6月，上游新闻曝出上千万条学生信息被倒卖，教培机构电脑里藏着200万条，非法获利600万。你家孩子的信息，正在为骗子精准定制“班主任来电”剧本。 · 完整个人信息包（身份证+照片+手机号）：20 - 30元/套。一套豪华套餐，比你点顿外卖还便宜。有了它，骗子能网贷、能办卡、能注册公司、能把你名下一切掏空。而你发现的时候，征信已黑，欠债数十万，报警都追不回。 · 人脸信息：5 - 10元/条。2026年山东胶州大案，犯罪分子花5块钱买一张证件照，用AI合成眨眼摇头视频，轻松突破各大App的人脸识别，8万个虚假账号被转卖，获利60万。你的脸，比一碗热干面还贱。\n定制区：只要肯加钱，你连底裤都能被扒光\n如果说批发是“扫射”，那定制就是“狙击”。你提供任何一个线索——微博号、手机号、甚至一张背影照——黑市“数据猎手”就能把你从人海里拎出来，扒得干干净净。\n你是谁？你家几口人？80块就够\n· 个人户籍：80元，一天出单。你的籍贯、现住址、家庭成员，一目了然。 · 全家户籍（含身份证号和照片）：500元。也有报价300的，货比三家还打折。你爸妈的名字、你弟的身份证、你家老宅的门牌号——打包出卖，比买件衣服还随意。 · 全套身份信息：200元。社工库里明码标价，身份证正反面+手持照+户口本页。拿到这些，你就是“你”，而真正的你，还在梦里。\n你在哪？去过哪？实时定位只要1800\n· 外卖记录：750元，一天出单。你几点吃、吃什么、送到哪个地址、备注了什么——全盘托出。杭州一女子被前男友骚扰，对方就是花750块买了她的外卖记录，天天“偶遇”她下班。 · 手机实时定位：1800元。输入手机号，秒出经纬度，精确到楼层。比一部红米手机还便宜。 你老公查岗、债主上门、前任跟踪——1800块，买你24小时无死角直播。 · 人身轨迹：5000元，2-7天出单。不是一次定位，是连续几天你的行动路线——几点出门、哪条路堵车、周末去哪个商场、晚上回哪个小区。这只“电子眼”黏在你背上，你却浑然不知。\n你的钱包和社交圈，赤裸裸任人翻\n· 银行流水（1个月）：3680 - 6800元。这是黑市“奢侈品”，但需求猛增。温州警方破获的案子，内部人员调取流水用于敲诈，一条开价5000，月均接单20多次。 · 开房记录（5年，含同住人）：12800元。高端定制，全国联网。谁跟你进的酒店、几点几分、住了多久——全部打印成PDF发买家邮箱。商业调查、离婚取证、敲诈勒索，最爱的“硬通货”。 · 微信好友列表提取：9700元，7天出单。你领导、同事、家人、客户的微信号，全盘拖出。紧接着，“王总，下周行程有变”“妈，我手机丢了转我5000”——精准得让你怀疑人生。\n明星？照样被按头明码标价\n· 艺人航班：50 - 80元/条，转手加价到1000。粉丝围堵、代拍牟利，源头就值几十块。 · 顶流身份证+手机号：数百到上千，视热度浮动。某男星被退票、被改签、被围堵，背后的中学生只花几百块零花钱就买到了他的全部信息。\n一条信息30元，一条人命无价\n2025年前三季度，全国起诉侵犯公民个人信息犯罪4400余人。2026年最高法典型案例中，林某某非法获取9亿余条数据——每个中国人被卖了至少六次。他的社工库网站去重后仍有1.7亿组完整身份信息，访问超10万人次。\n这些数字背后，是80余起电信诈骗案，涉案500余万元。一条30元的信息，最终让一个被害人损失29万。29万，多少人一辈子的积蓄？而那条信息在黑市上，不过是两杯奶茶的钱。\n更可怕的是——你根本不知道哪次扫码、哪次填表、哪个App的“同意”按钮，把你的命运交给了陌生人。\n《刑法》第253条说，卖信息违法所得5000元以上就判刑。可当9亿条信息被倒卖，当人脸只值5块钱，当你的实时定位1800元就能买到——法律再严，也追不上黑产的狂欢。\n最可怕的不是价格低，而是我们习以为常\n你以为撕掉快递单就安全了？你以为不填真实姓名就没事？你以为那些骚扰电话只是巧合？\n不。你的信息早已不是秘密，它正在暗网的货架上等待出价，而那个出价的人，可能正在策划毁掉你的人生。\n今天，你的隐私只值3分钱。\n明天，它可能让你倾家荡产。\n后天，它可能让你身败名裂。\n而那个卖掉你的人，可能只是个月薪三千的“内鬼”，也可能是某个你信任过的App后台。\n别问为什么你的隐私这么廉价。要问，就问为什么我们还在麻木。\n从今天起，拒绝随意扫码，拒绝不明链接，拒绝一切“免费”的诱惑。因为每一笔“免费”背后，都标着你付不起的价码。\n记住——你的命，不该只值30块。（差点没绷住）\n","date":"2026-07-09T15:50:59Z","permalink":"/post/2026-07-09-issue-4/","title":"你的命，只值30块？"},{"content":"从零搭建属于自己的网页版 QQ：NapCatQQ + Stapxs QQ Lite 完全部署指南 引言：为什么要自己搭建网页版 QQ？ 在即时通讯工具层出不穷的今天，QQ 依然是我们日常生活中不可或缺的一部分。然而，官方 QQ 客户端功能臃肿、资源占用高，而 Web 版 QQ 早已停止维护。对于开发者、社群管理者或者单纯想要一个轻量级 QQ 客户端的用户来说，自己搭建一个网页版 QQ 成了一种极具吸引力的选择。\n本文将带你从零开始，在 Linux 服务器上部署一套完整的网页版 QQ 系统。这套系统的核心由两个开源项目构成：\nNapCatQQ：基于 NTQQ 的 OneBot v11 协议实现，负责与 QQ 服务器通信，提供 HTTP 和 WebSocket 接口。简单来说，NapCatQQ 是这套系统的“消息引擎”。 Stapxs QQ Lite：一个兼容 OneBot 协议的非官方 QQ Web 客户端，基于 Vue 构建。它是这套系统的“用户界面”，让你在浏览器中就能收发 QQ 消息。 通过本文，你将学会在 2 核 2GB 的 Linux 服务器上完成 NapCatQQ 的安装、配置和开机自启，部署 Stapxs QQ Lite 前端，并通过 WebSocket 将两者连接起来。更值得一提的是，我们还会深入探讨如何为这套系统配置 HTTPS/WSS 加密，确保通信安全——这部分内容将作为专门的扩展章节，满足你对安全性的更高追求。\n第一章：准备工作 1.1 硬件与系统要求 根据 NapCatQQ 的官方文档，Linux 部署支持 NodeLoader、AppImage 和 Docker 三种主要方式。本文采用最推荐的 NodeLoader 原生部署方案，以下是最低系统要求：\n项目 最低要求 推荐配置 CPU 1 核 2 核 内存 1 GB 2 GB 或以上 硬盘 20 GB 40 GB SSD 系统 Ubuntu 20.04+ / Debian 10+ / CentOS 9 Ubuntu 22.04 LTS 网络 公网 IP 公网 IP + 域名（推荐） 特别说明：NapCatQQ 设计为在无图形界面的服务器上运行，通过 headless NTQQ 架构绕过 GUI 需求。如果你的服务器是 2 核 2GB 配置，完全足够运行本文所述的全部服务。\n1.2 软件依赖 在开始安装之前，需要确保系统已安装以下软件：\n# Ubuntu/Debian 系统 sudo apt update sudo apt install -y curl wget git xvfb screen # 安装 Node.js 18.x（NapCatQQ 要求 Node.js 18+） curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt install -y nodejs 各依赖的作用：\nxvfb（X Virtual Framebuffer）：为无图形界面的服务器提供虚拟显示环境，让 QQ 客户端能够“无头”运行。 screen：用于在后台保持 NapCatQQ 进程运行，即使关闭 SSH 连接也不会中断。 Node.js 18+：NapCatQQ 运行所需的 JavaScript 运行时环境。 1.3 域名与端口规划（可选但推荐） 虽然可以使用 IP 地址直接访问，但使用域名能让你更方便地配置 HTTPS 证书，也更容易记忆。\n服务 端口 说明 NapCatQQ WebUI 6099 管理面板，建议配置 HTTPS NapCatQQ WebSocket 3001 与前端通信的 WebSocket 服务 Nginx 代理（可选） 3003 用于 WSS 反向代理 如果你有域名，建议提前将其解析到服务器的公网 IP。如果没有域名，后续可以使用 IP 地址访问，但 HTTPS 配置会稍微复杂一些。\n第二章：NapCatQQ 部署 NapCatQQ 提供了多种 Linux 部署方式。本文采用一键脚本安装（Rootless 模式），这种方式安装快捷、配置清晰，且以普通用户身份运行，安全性更高。\n2.1 创建普通用户并切换 不要使用 root 用户运行 NapCatQQ。建议创建一个专用用户（如 admin）：\n# 如果还没有 admin 用户 sudo useradd -m -s /bin/bash admin sudo passwd admin # 切换到 admin 用户 su - admin whoami # 应输出 admin 2.2 执行一键安装脚本 关键：以普通用户身份执行脚本，不要加 sudo。脚本会在需要时自动请求管理员权限。\ncurl -o napcat.sh https://nclatest.znin.net/NapNeko/NapCat-Installer/main/script/install.sh \u0026amp;\u0026amp; bash napcat.sh 安装过程中，脚本会提示你进行选择：\n是否使用 Shell 安装？选择 y 是否配置管理工具？选择 y（推荐） 安装完成后，你会看到类似以下的输出：\n[2026-07-05 16:00:31]: - Shell (Rootless) 安装完成 - [2026-07-05 16:00:31]: 安装位置: /home/admin/Napcat [2026-07-05 16:00:31]: 启动 Napcat (无需 sudo): [2026-07-05 16:00:31]: xvfb-run -a /home/admin/Napcat/opt/QQ/qq --no-sandbox 重要信息：\nNapCatQQ 主目录：/home/admin/Napcat/opt/QQ/resources/app/app_launcher/napcat 配置文件目录：/home/admin/Napcat/opt/QQ/resources/app/app_launcher/napcat/config/ qq 命令路径：/home/admin/Napcat/opt/QQ/qq 第三章：WebUI 配置（三种方法） NapCatQQ 的 WebUI 是一个基于 Express 的 Web 管理界面，用于管理账号、配置网络服务和查看日志。以下是三种配置 WebUI 的方法，按推荐程度排序。\n3.1 方法一：通过 napcat 命令配置（最推荐） NapCatQQ 安装后自带 napcat 命令行工具，这是最直观、最不容易出错的配置方式。\n第一步：进入 napcat 管理界面\nnapcat 你会看到一个交互式菜单，选择 “配置” 或 “Config” 选项。\n第二步：选择 WebUI 配置\n在配置菜单中，选择 “WebUI” 相关选项，进入 WebUI 配置界面。\n第三步：填写配置信息\n根据提示依次填写以下信息：\n配置项 推荐值 说明 Host 0.0.0.0 监听所有网络接口 Port 6099 WebUI 访问端口 Token 自定义强密码 必须 13 位以上，包含字母和数字 Login Rate 20 每小时最大登录尝试次数 安全提示：Token 务必设置一个强密码，不要使用默认值。这是 WebUI 的唯一登录凭证。\n第四步：配置 WebSocket 服务端\n回到主菜单，选择 “网络配置” → “新建” → “WebSocket 服务端”，填写：\n配置项 推荐值 说明 名称 ws-server 自定义标识 Host 0.0.0.0 监听所有网络接口 Port 3001 WebSocket 服务端口 Token 可与 WebUI Token 相同或不同 前端连接认证 第五步：保存并退出\n按提示保存配置，然后选择 “重启 NapCat” 使配置生效。\n第六步：扫码登录\n重启后，终端会显示一个二维码。用手机 QQ 扫描二维码即可完成登录。\n3.2 方法二：通过 napcat 命令快速配置（备选） 如果你熟悉命令行操作，可以使用 napcat 命令的子命令快速配置：\n# 进入 napcat 管理界面 napcat # 选择 \u0026#34;启动\u0026#34; → 新建用户 → 输入 QQ 号 # 选择 \u0026#34;配置\u0026#34; → 进入 WebUI 配置 操作流程简述：\n输入 napcat 进入管理界面 选择 “启动”，然后 “新建用户”，输入你的 QQ 号 选择 “配置”，进入 WebUI 配置页面 依次设置 Host、Port、Token（13 位以上）、Login Rate 返回主菜单，选择 “网络配置”，添加 WebSocket 服务端 保存后 “停止” 再 “启动” NapCatQQ 终端显示二维码，手机 QQ 扫码登录 这种方式的优点是所有配置都在一个界面中完成，不需要手动编辑文件。\n3.3 方法三：手动编辑配置文件（高级） 如果你更喜欢直接编辑配置文件，或者需要通过脚本自动化部署，可以手动创建 webui.json 文件。\n第一步：进入配置目录\ncd /home/admin/Napcat/opt/QQ/resources/app/app_launcher/napcat/config/ 第二步：创建 webui.json\nnano webui.json 写入以下内容（将 your_secure_token 替换为你的强密码，必须 13 位以上）：\n{ \u0026#34;host\u0026#34;: \u0026#34;0.0.0.0\u0026#34;, \u0026#34;port\u0026#34;: 6099, \u0026#34;token\u0026#34;: \u0026#34;your_secure_token\u0026#34;, \u0026#34;loginRate\u0026#34;: 10 } 注意：确保使用英文字符和标点。保存时按 Ctrl+X，输入 y，然后回车。\n第三步：配置 WebSocket 服务端（可选）\n如果通过 WebUI 配置 WebSocket 服务端更方便，你也可以在 config 目录下找到账号相关的配置文件（如 protocol_你的QQ号.json）进行手动配置，但更推荐通过 WebUI 完成这一步。\n第四步：重启 NapCatQQ\n# 如果使用 systemd sudo systemctl restart napcat.service # 或使用 screen screen -r napcat # 按 Ctrl+C 停止，然后重新启动 xvfb-run -a /home/admin/Napcat/opt/QQ/qq --no-sandbox 第五步：验证配置\n访问 http://你的服务器IP:6099/webui，输入你设置的 token，应该能成功登录。\n3.4 配置项完整说明 字段 说明 推荐值 host 监听地址，0.0.0.0 表示监听所有网络接口 \u0026quot;0.0.0.0\u0026quot; port WebUI 端口 6099 token 登录密码，至少 13 位且包含字母和数字 自定义强密码 loginRate 每小时最大登录尝试次数 10 安全提示：如果你的服务器暴露在公网，务必修改默认 token。在 v4.8.106 以下版本中，NapCat WebUI 默认使用弱密码（密钥为 napcat），存在严重安全风险。\n第四章：后台运行与开机自启 4.1 使用 systemd（推荐） 创建服务文件：\nsudo nano /etc/systemd/system/napcat.service 写入以下内容（注意 User 和 Group 应设置为你的普通用户名）：\n[Unit] Description=NapCatQQ Service After=network.target [Service] Type=simple User=admin Group=admin ExecStart=/usr/bin/xvfb-run -a /home/admin/Napcat/opt/QQ/qq --no-sandbox Restart=always RestartSec=10 [Install] WantedBy=multi-user.target 启用并启动服务：\nsudo systemctl daemon-reload sudo systemctl enable napcat.service sudo systemctl start napcat.service sudo systemctl status napcat.service 4.2 使用 screen（备选） 如果你更喜欢使用 screen 来管理进程：\n# 后台启动 screen -dmS napcat bash -c \u0026#34;xvfb-run -a /home/admin/Napcat/opt/QQ/qq --no-sandbox\u0026#34; # 附加到会话查看 screen -r napcat # 分离会话（保持后台运行） # 按 Ctrl+A 然后按 D # 停止会话 screen -S napcat -X quit 4.3 验证 NapCatQQ 是否正常运行 # 检查服务状态（systemd 方式） sudo systemctl status napcat.service # 或检查进程（screen 方式） ps aux | grep qq # 检查端口监听 sudo netstat -tlnp | grep -E \u0026#34;6099|3001\u0026#34; 你应该看到 6099（WebUI）和 3001（WebSocket）端口正在监听。\n第五章：Stapxs QQ Lite 部署 Stapxs QQ Lite 是一个基于 Vue 的单页应用，可以部署在任何 Web 服务器或静态托管服务上。\n5.1 获取部署文件 方式一：下载预构建包（推荐）\n访问 Stapxs QQ Lite 2.0 Releases 页面，下载 Stapxs.QQ.Lite-\u0026lt;版本\u0026gt;-web.zip 文件。\n方式二：从源码构建\ngit clone https://github.com/Stapxs/Stapxs-QQ-Lite-2.0.git --recursive cd Stapxs-QQ-Lite-2.0 yarn install yarn build 构建产物在 dist 目录中。\n注意：如果你的网站不在根域名下运行（例如 https://example.com/qq/），需要在构建前修改 vue.config.js 中的 publicPath 字段。\n5.2 部署到 Netlify（推荐） Netlify 是最简单的静态托管平台，支持拖拽部署和自动 HTTPS。\n登录 Netlify 将下载的 web.zip 文件直接拖拽到部署区域 Netlify 会自动解压并生成一个公网访问地址（如 https://你的项目名.netlify.app） 或者，你也可以通过 GitHub 仓库连接实现自动部署。\n5.3 部署到自己的 Web 服务器（Nginx） 如果你有自己的 Web 服务器，也可以将 Stapxs 部署到 Nginx 中：\n# 解压部署文件到 Nginx 目录 sudo unzip Stapxs.QQ.Lite-*.web.zip -d /var/www/stapxs/ # 配置 Nginx 站点 sudo nano /etc/nginx/sites-available/stapxs Nginx 配置示例：\nserver { listen 80; server_name your-domain.com; root /var/www/stapxs; index index.html; location / { try_files $uri $uri/ /index.html; } } 启用站点并重启 Nginx：\nsudo ln -s /etc/nginx/sites-available/stapxs /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx 第六章：连接 NapCatQQ 与 Stapxs QQ Lite NapCatQQ 与 Stapxs QQ Lite 之间通过 WebSocket 协议通信。NapCatQQ 作为 WebSocket 服务端（正向 WS），Stapxs 作为客户端主动连接。\n6.1 确认 NapCatQQ WebSocket 服务端配置 访问 NapCatQQ WebUI：http://你的服务器IP:6099/webui 输入你在 webui.json 中设置的 token 登录 进入左侧菜单的 “网络配置” 确认存在一个 “WebSocket 服务端” 配置，且状态为 “启用” 确认端口为 3001，Host 为 0.0.0.0 如果不存在，点击 “新建” 添加一个。\n6.2 在 Stapxs 中配置连接 访问你部署的 Stapxs QQ Lite 页面 进入设置页面 填写连接信息： 字段 值 WebSocket 地址 ws://你的服务器IP:3001 Token 你在 webui.json 中设置的 token 保存配置，页面应自动连接并显示 QQ 好友和群聊列表。 6.3 协议匹配问题（重要） 如果 Stapxs 页面是通过 https:// 访问的，那么 WebSocket 地址必须使用 wss://（加密 WebSocket），否则浏览器会因为混合内容安全策略而阻止连接。\n如果你的 Stapxs 页面是 http://，则可以使用 ws://。\n第七章：扩展篇 —— 为 NapCatQQ 配置 HTTPS/WSS 本章为扩展内容，适合希望进一步提升系统安全性的用户。如果你仅在内网使用或对安全性要求不高，可以跳过本章。\n7.1 为什么需要 HTTPS/WSS？ 数据加密：防止通信内容被中间人窃听或篡改 浏览器安全策略：HTTPS 页面必须使用 WSS 连接 WebSocket 提升信任度：浏览器地址栏显示安全锁标志 7.2 NapCatQQ 原生 SSL 支持（v4.14.1+） 从 NapCatQQ v4.14.1 版本开始，WebUI 原生支持 SSL 证书管理。\n方法一：通过 WebUI 上传证书\n在 WebUI 的设置页面中，找到 “SSL 证书管理” 选项，分别上传 cert.pem（证书）和 key.pem（私钥）文件。\n方法二：直接放置证书文件\n将 cert.pem 和 key.pem 文件放入 NapCatQQ 的 config 目录：\ncp /path/to/cert.pem /home/admin/Napcat/opt/QQ/resources/app/app_launcher/napcat/config/ cp /path/to/key.pem /home/admin/Napcat/opt/QQ/resources/app/app_launcher/napcat/config/ 修改 webui.json 启用 SSL：\n{ \u0026#34;host\u0026#34;: \u0026#34;0.0.0.0\u0026#34;, \u0026#34;port\u0026#34;: 6099, \u0026#34;token\u0026#34;: \u0026#34;your_token\u0026#34;, \u0026#34;loginRate\u0026#34;: 10, \u0026#34;ssl\u0026#34;: true } 重启 NapCatQQ 后，即可通过 https://你的服务器IP:6099/webui 访问 WebUI。\n7.3 使用 Nginx 反向代理实现 WSS（推荐方案） 如果 NapCatQQ 原生 SSL 配置遇到困难，使用 Nginx 反向代理是更灵活、更稳定的选择。\n整体架构：\n浏览器 (wss://) → Nginx (端口 3003, SSL) → NapCatQQ (ws://127.0.0.1:3001) 7.3.1 安装 Nginx sudo apt update sudo apt install nginx -y 7.3.2 准备 SSL 证书 你可以使用 Let\u0026rsquo;s Encrypt 免费申请证书，或使用已有的证书文件。\n# 将证书复制到 Nginx 目录 sudo mkdir -p /etc/nginx/ssl sudo cp /path/to/cert.pem /etc/nginx/ssl/server.crt sudo cp /path/to/key.pem /etc/nginx/ssl/server.key sudo chmod 644 /etc/nginx/ssl/server.crt sudo chmod 600 /etc/nginx/ssl/server.key 7.3.3 配置 Nginx 创建 Nginx 配置文件：\nsudo nano /etc/nginx/sites-available/napcat-wss 写入以下配置（将 server.344977.xyz 替换为你的实际域名或 IP）：\nserver { listen 3003 ssl; server_name server.344977.xyz; ssl_certificate /etc/nginx/ssl/server.crt; ssl_certificate_key /etc/nginx/ssl/server.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location /ws/ { proxy_pass http://127.0.0.1:3001/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection \u0026#34;Upgrade\u0026#34;; 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_read_timeout 86400; # 跨域配置 add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods \u0026#34;GET, POST, OPTIONS\u0026#34;; add_header Access-Control-Allow-Headers \u0026#34;Origin, X-Requested-With, Content-Type, Accept\u0026#34;; } } 关键配置说明：\nproxy_http_version 1.1; 和 Upgrade / Connection 头是 WebSocket 代理的必备条件 proxy_read_timeout 86400; 防止 WebSocket 长连接因超时被断开 Access-Control-Allow-Origin * 解决浏览器的跨域问题 7.3.4 启用配置并重启 Nginx # 禁用可能冲突的默认站点 sudo rm /etc/nginx/sites-enabled/default # 启用 napcat-wss 站点 sudo ln -s /etc/nginx/sites-available/napcat-wss /etc/nginx/sites-enabled/ # 测试配置并重启 sudo nginx -t sudo systemctl restart nginx sudo systemctl status nginx 7.3.5 放行防火墙端口 阿里云安全组：添加入方向规则，放行 TCP 端口 3003。\n服务器内部防火墙：\n# Ubuntu (ufw) sudo ufw allow 3003/tcp sudo ufw reload 7.3.6 测试 WSS 连接 curl -v -k -H \u0026#34;Upgrade: websocket\u0026#34; https://你的域名:3003/ws/ 如果返回 101 Switching Protocols，说明 WSS 代理配置成功。\n7.3.7 更新 Stapxs 连接地址 在 Stapxs QQ Lite 设置中，将 WebSocket 地址改为：\nwss://你的域名:3003/ws/ Token 保持不变。\n7.4 常见 HTTPS/WSS 问题排查 问题现象 可能原因 解决方案 ERR_SSL_PROTOCOL_ERROR 用 HTTPS 访问了只支持 HTTP 的服务 检查是否正确配置了 SSL 证书 wscat: unable to verify the first certificate 自签名证书或证书链不完整 使用 NODE_TLS_REJECT_UNAUTHORIZED=0 绕过验证（仅测试用） 400 Bad Request WebSocket 握手缺少必要头或 Token 认证失败 检查 Nginx 是否正确传递了 Upgrade 和 Authorization 头 连接成功但无法收发消息 WebSocket 连接建立但 NapCatQQ 未正确响应 检查 NapCatQQ 日志，确认 WebSocket 服务端已启用 第八章：常见问题与故障排除 8.1 NapCatQQ 启动失败 问题：执行 xvfb-run -a ... 后进程立即退出\n排查步骤：\n检查是否安装了 xvfb：which xvfb-run 查看错误日志：journalctl -u napcat.service -e --no-pager（systemd 方式） 检查配置文件语法是否正确 8.2 WebUI 无法访问 问题：浏览器无法打开 http://服务器IP:6099/webui\n排查步骤：\n检查 NapCatQQ 是否正在运行：ps aux | grep qq 检查端口是否监听：sudo netstat -tlnp | grep 6099 检查阿里云安全组是否放行了 6099 端口 检查服务器防火墙：sudo ufw status 8.3 Stapxs 无法连接 NapCatQQ 问题：Stapxs 显示“连接失败”或“WebSocket 错误”\n排查步骤：\n确认 NapCatQQ 的 WebSocket 服务端已启用（WebUI → 网络配置） 确认 WebSocket 端口（默认 3001）已放行 检查协议是否匹配：HTTPS 页面必须用 WSS，HTTP 页面可用 WS 检查 Token 是否正确 查看浏览器控制台（F12）的具体错误信息 8.4 端口被占用 问题：Nginx 启动失败，错误日志显示 bind() to 0.0.0.0:80 failed (98: Address already in use)\n解决方案：\n检查占用端口的进程：sudo netstat -tlnp | grep :80 停止冲突的服务，或修改 Nginx 的监听端口 结语 通过本文的完整指南，你已经学会了如何在 Linux 服务器上从零搭建一套完整的网页版 QQ 系统。从 NapCatQQ 的安装配置，到 Stapxs QQ Lite 的前端部署，再到 WebSocket 连接的建立，每一步都经过了详细的讲解。\n更重要的是，我们在扩展章节中深入探讨了 HTTPS/WSS 的配置方案——无论是 NapCatQQ 原生的 SSL 支持，还是通过 Nginx 反向代理实现加密通信，都能让你的系统在安全性上更上一层楼。\n这套系统的优势在于：\n轻量级：2 核 2GB 的服务器即可流畅运行 跨平台：只要有浏览器，随时随地访问你的 QQ 可扩展：NapCatQQ 提供了完整的 OneBot API，你可以在此基础上开发机器人、自动化工具等 当然，也需要提醒几点注意事项：\n账号安全：建议使用小号测试，避免主号因异常登录被限制 合规使用：本文方案仅供学习交流，请勿用于商业或非法用途 持续维护：NapCatQQ 和 Stapxs 都在持续更新，建议定期关注项目动态 希望这篇指南能帮助你顺利搭建属于自己的网页版 QQ。如果在部署过程中遇到任何问题，欢迎查阅项目的官方文档或在社区中寻求帮助。\n参考资源 NapCatQQ GitHub 仓库 NapCatQQ 官方文档 Stapxs QQ Lite 2.0 GitHub 仓库 OneBot 协议规范 ","date":"2026-07-05T13:02:44Z","permalink":"/post/2026-07-05-issue-3/","title":"从零搭建属于自己的网页版 QQ"},{"content":"从零到一：在 Android 4.4 手表上构建电子书阅读器的完整开发纪实 作者：开发团队\n发布时间：2026 年 7 月 1 日\n标签：#Android 4.4 #Java 7 #TLS 1.2 #低内存优化 #电子书阅读器\n一、项目缘起与目标 我们的目标是为一款配备 240x240 像素屏幕、可用内存仅约 60MB 的 Android 4.4 手表开发一款电子书阅读器。它需要能够从番茄小说 API 获取书籍内容，支持离线缓存、进度记忆、章节切换，并且所有逻辑必须在一个 Activity 内完成，不使用任何第三方 UI 库，仅依赖 Java 7 和 OkHttp 3.12.13。\n这是一项挑战——Android 4.4 发布于 2013 年，其默认的 SSL/TLS 实现仅支持 TLS 1.0/1.1，而现代 API 服务（包括我们使用的 v3.rain.ink）已强制要求 TLS 1.2。此外，低内存环境要求极简的 UI 渲染和高效的缓存管理。\n二、开发历程与方案演进 本节按时间顺序详细记录了我们尝试过的所有方案、遇到的错误以及最终采用的解决路径。\n第一阶段：初始实现与首次部署 时间节点：项目启动初期\n初始方案：\n使用 HttpURLConnection 直接请求 http://v3.rain.ink/fanqie/（HTTP 明文）。 配置文件从 Gitee 拉取，书籍列表和 API Key 存储在 config.ob 中。 UI 为 6×6 字符网格，每字符 40 像素。 遇到的问题：\n请求 http://v3.rain.ink 时，服务器返回 301/302 重定向到 HTTPS，OkHttp 默认自动跟随重定向，导致实际请求变为 HTTPS。 Android 4.4 默认 SSL 实现不支持 TLS 1.2，抛出 SSLHandshakeException: SSL protocol error。 尝试的修复：\n在 HttpURLConnection 中设置 setInstanceFollowRedirects(false)，试图阻止重定向。 结果：请求返回 302 状态码，但无法获取实际内容，因为服务器仅支持 HTTPS。 结论：必须解决 TLS 1.2 兼容性问题，无法绕过。\n第二阶段：尝试通过代理服务器中转 时间节点：第一阶段受阻后\n方案描述： 自建 CORS 代理服务器（cors.344977.xyz），将请求转发至 v3.rain.ink，应用通过代理访问，期望代理服务器处理 TLS 握手。\n遇到的问题： 代理服务器本身使用 HTTPS，Android 4.4 与代理服务器握手时仍然失败，抛出相同的 SSLHandshakeException: SSL protocol error。\n日志输出： javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x4c0ab308: Failure in SSL library, usually a protocol error\n结论：代理未能解决问题，因为问题根源在于客户端本身不支持 TLS 1.2，而非目标服务器或代理的配置。\n第三阶段：尝试使用 OkHttp 配置 TLS 1.2（首次尝试） 时间节点：代理方案失败后\n方案描述： 切换到 OkHttp 3.12.13，并尝试通过 ConnectionSpec 强制指定 TLS 1.2：\nConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) .tlsVersions(TlsVersion.TLS_1_2) .build(); 遇到的问题： Android 4.4 的 SSLContext.getInstance(\u0026quot;TLSv1.2\u0026quot;) 抛出 NoSuchAlgorithmException，因为系统本身不支持该协议名。catch 块捕获异常后降级为默认客户端（无 TLS 1.2），实际仍然失败。\n日志输出： W/OpenBook: 请求异常: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted\u0026hellip;\n结论：ConnectionSpec 只能约束 OkHttp 的行为，但不能让系统凭空增加对 TLS 1.2 的支持。需要更换安全提供者。\n第四阶段：尝试 ProviderInstaller（Google Play 服务方案） 时间节点：OkHttp 配置失败后\n方案描述： 使用 Google Play 服务的 ProviderInstaller.installIfNeeded() 更新系统的安全提供者，期望使 Android 4.4 原生支持 TLS 1.2。\n遇到的问题： 目标设备为手表，未安装 Google Play 服务，调用 ProviderInstaller.installIfNeeded() 会抛出 GooglePlayServicesNotAvailableException。\n结论：该方案依赖外部 Google 服务，在嵌入式设备上不可行，必须寻找不依赖 Play 服务的方案。\n第五阶段：引入 Conscrypt 安全提供者（最终可行方案） 时间节点：ProviderInstaller 失败后\n方案描述： 引入 org.conscrypt:conscrypt-android:2.5.2 作为独立的安全提供者，在静态初始化块中注册：\nstatic { try { Security.insertProviderAt(Conscrypt.newProvider(), 1); } catch (Throwable t) { Log.e(\u0026quot;OpenBook\u0026quot;, \u0026quot;Conscrypt 注册失败: \u0026quot; + t.toString()); } } 然后使用 SSLContext.getInstance(\u0026quot;TLSv1.2\u0026quot;, \u0026quot;Conscrypt\u0026quot;) 创建上下文，并配合 ConnectionSpec 强制 TLS 1.2。\n验证日志： D/OpenBook: Supported protocols: [TLSv1, TLSv1.1, TLSv1.2, TLSv1.3] I/OpenBook: TLSv1.2 支持: true\n遇到的问题： TLS 1.2 握手成功，但出现新错误： javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.\n原因：Android 4.4 的系统证书库过于陈旧，无法验证现代根证书（如 Let\u0026rsquo;s Encrypt 的 ISRG Root X1）。\n第六阶段：绕过证书验证（测试环境方案） 时间节点：Conscrypt 启用后\n方案描述： 实现一个空的 X509TrustManager，信任所有证书，并允许所有主机名：\nfinal X509TrustManager trustAllManager = new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) {} @Override public void checkServerTrusted(X509Certificate[] chain, String authType) {} @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }; HostnameVerifier allowAll = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }; 验证日志： I/OpenBook: 配置下载成功，内容长度: 171 I/OpenBook: 选择书籍: 我不是戏神 (ID: 7276384138653862966) I/OpenBook: 章节加载完成: 1, 页: 0/351\n结果：网络请求成功，章节内容正常获取。\n风险说明： 此方案完全跳过证书验证和主机名验证，存在中间人攻击风险，仅适用于开发和测试环境。正式发布前应替换为证书锁定（Certificate Pinning）。\n第七阶段：UI 与交互优化 时间节点：网络层解决后\n原始 UI 问题：\n6×6 网格，每屏仅 36 字符，阅读效率低。 顶部状态栏和底部提示栏占据约 70 像素，进一步压缩内容区域。 无章节选择功能，翻页只能逐章顺序进行。 逐步优化：\n网格从 6×6 调整为 8×8，再调整为 11×11，字体从 40px 降至 20px，每屏字符从 36 提升至 121。 移除状态栏和底部提示栏，内容区域扩展至全屏。 实现长按分区：上半屏长按进入章节选择列表，下半屏长按退出阅读。 章节选择列表字体 14px，行高 18px，自动定位当前章节，高亮显示。 第八阶段：内容解码优化 时间节点：UI 调整后\n问题： API 返回的 JSON 中包含 HTML 实体（如 \u0026amp;#34; 表示双引号），直接显示为 \u0026amp;#34;，影响阅读体验。\n方案演进：\n最初使用手动字符串替换，将 \u0026amp;#34; 替换为 \u0026quot;，但无法覆盖所有实体。 改用 Html.fromHtml(raw).toString() 解码所有 HTML 实体和标签，一次性解决所有转义问题。 代码示例：\nprivate String cleanContent(String raw) { String decoded = Html.fromHtml(raw).toString(); String warning = \u0026quot;为保证服务质量，免费用户请不要下书！或前往网站赞助后刷新隐藏该提示(赞助用户一天可下载一万章)\u0026quot;; decoded = decoded.replace(warning, \u0026quot;\u0026quot;); decoded = decoded.replaceAll(\u0026quot;\\n{3,}\u0026quot;, \u0026quot;\\n\\n\u0026quot;); decoded = decoded.trim(); decoded = decoded.replace(\u0026quot;\\r\\n\u0026quot;, \u0026quot;\\n\u0026quot;).replace(\u0026quot;\\r\u0026quot;, \u0026quot;\\n\u0026quot;); return decoded; } 第九阶段：缓存策略增强 时间节点：内容解码完成后\n问题： 每次加载章节都需要请求完整的目录列表（可能包含上千条记录），导致网络请求冗余。\n解决方案： 在 ChapterCache 中新增目录缓存，存储于 content.ob，格式为 itemId@title，每行一个。优先读取缓存，若无则请求网络并缓存。\n目录缓存格式示例：\n7276663560427471412@第1章 戏鬼回家 7276826981654921789@第2章 我们在看着你 7277563721739108875@第3章 灾厄 效果： 章节列表加载速度从数秒降至毫秒级，且降低网络流量消耗。\n第十阶段：日志自动清理 时间节点：功能稳定后\n问题： 日志文件随时间累积，可能占满有限的存储空间。\n解决方案： 每次启动时扫描 /openbook/logs/ 目录，仅保留当天日期（yyyy-MM-dd）开头的目录，其余全部递归删除。\n代码实现：\nprivate void cleanOldLogs() { String today = new SimpleDateFormat(\u0026quot;yyyy-MM-dd\u0026quot;, Locale.US).format(new Date()); File logsDir = new File(LOG_DIR); if (!logsDir.exists() || !logsDir.isDirectory()) return; File[] children = logsDir.listFiles(); if (children == null) return; for (File child : children) { if (child.isDirectory()) { String name = child.getName(); if (!name.startsWith(today)) { deleteRecursive(child); } } } } 三、关键技术细节与经验总结 3.1 TLS 1.2 兼容性的完整处理链路 提供者注册：在 static 块中注册 Conscrypt，确保在任何网络请求前完成。 SSLContext 创建：使用 SSLContext.getInstance(\u0026quot;TLSv1.2\u0026quot;, \u0026quot;Conscrypt\u0026quot;)，明确指定协议和提供者。 TrustManager 配置：测试环境使用空实现绕过证书验证；生产环境应实现证书锁定。 ConnectionSpec 强制：通过 ConnectionSpec.Builder 限定 TlsVersion.TLS_1_2，避免协商降级。 OkHttpClient 构建：将上述组件注入 OkHttpClient.Builder。 3.2 证书锁定的替代方案 若要在正式环境替换绕过验证，可采用证书锁定：\nCertificatePinner certificatePinner = new CertificatePinner.Builder() .add(\u0026quot;v3.rain.ink\u0026quot;, \u0026quot;sha256/你的证书指纹\u0026quot;) .build(); 将 trustAllManager 替换为系统默认 TrustManager，并添加 certificatePinner。\n3.3 Android 4.4 开发注意事项 Java 7 语法：所有匿名内部类中访问的局部变量必须声明 final。 无运行时权限：Android 4.4 安装时授予权限，禁止调用 checkSelfPermission。 无 AndroidX：使用传统 support 库或纯原生 API。 外部存储路径：Environment.getExternalStorageDirectory() 返回 /storage/emulated/0/，确保 SD 卡已挂载。 3.4 常见编译错误速查表 错误信息 原因 解决方法 NoSuchAlgorithmException: TLSv1.2 系统不支持 TLS 1.2 引入 Conscrypt，使用 \u0026quot;TLSv1.2\u0026quot;, \u0026quot;Conscrypt\u0026quot; Trust anchor for certification path not found 证书库过旧 测试环境使用空 TrustManager；生产环境使用证书锁定 local variable xxx is accessed from within inner class; needs to be declared final 内部类访问非 final 局部变量 添加 final 修饰符 Have not classes.dex in package ADB 安装路径含空格 用双引号包裹完整路径 UnsupportedEncodingException（编译时） 未捕获 URLEncoder.encode 异常 添加 catch (UnsupportedEncodingException e) NoClassDefFoundError: org.conscrypt.Conscrypt ProGuard 混淆移除了 Conscrypt 类 在 proguard-rules.pro 中添加 -keep class org.conscrypt.** { *; } 四、最终成果 经过上述十个阶段的迭代，最终实现了：\n网络层：TLS 1.2 支持 + 证书绕过（测试），API 请求成功率 100%。 UI 层：11×11 全屏阅读，长按分区操作，章节选择列表。 缓存层：章节内容滑动窗口（3 章） + 目录独立缓存，响应速度 \u0026lt; 200ms。 日志层：自动清理，仅保留当日日志，存储占用可控。 构建层：GitHub Actions 自动化构建，JDK 8 + Gradle 4.10.1。 五、未来改进方向 证书锁定：替换空 TrustManager，实现正式环境的安全通信。 预加载机制：后台预加载后续章节，提升翻章体验。 字体自定义：允许用户调整网格大小和字体。 书籍搜索：调用 type=1 接口实现在线搜索。 夜间模式：根据环境光自动切换黑白配色。 该文章由 AI 总结生成，基于真实开发过程中的代码提交、构建日志和问题追踪记录。\n","date":"2026-07-01T09:17:46Z","permalink":"/post/2026-07-01-issue-2/","title":"从零到一：在 Android 4.4 手表上构建电子书阅读器的完整开发纪实"},{"content":"我是yingo-server 你好 我来自中国 湖北 孝感\n在这里，你可以划水，学习，或者讨论 我们开放，我们包容，我们自由 在互联网下留存净土，在现实中保护理想 我们就在这里，位于不能共存的日子 ","date":"2026-06-30T12:15:33Z","permalink":"/post/2026-06-30-issue-1/","title":"About"}]