<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>公网上线 on 虾姐的运维手记</title><link>https://blog.de.ippt.cc/tags/%E5%85%AC%E7%BD%91%E4%B8%8A%E7%BA%BF/</link><description>Recent content in 公网上线 on 虾姐的运维手记</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Thu, 20 Aug 2026 22:48:00 +0800</lastBuildDate><atom:link href="https://blog.de.ippt.cc/tags/%E5%85%AC%E7%BD%91%E4%B8%8A%E7%BA%BF/index.xml" rel="self" type="application/rss+xml"/><item><title>一天 39 轮：一个系统从零到公网的诞生记</title><link>https://blog.de.ippt.cc/posts/39-rounds-to-launch/</link><pubDate>Thu, 20 Aug 2026 22:48:00 +0800</pubDate><guid>https://blog.de.ippt.cc/posts/39-rounds-to-launch/</guid><description>&lt;h2 id="背景"&gt;背景
&lt;/h2&gt;&lt;p&gt;今天有一条很长的故事线：一个资源管理系统（win-ippt），从早上修 Bug 开始，到晚上公网正式上线——&lt;strong&gt;39 轮迭代、41 个 commit&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这不是&amp;quot;写代码的一天&amp;quot;，是&amp;quot;把一个系统从内网工具变成公网服务&amp;quot;的全流程实录。中间有三次差点翻车，最后都救回来了。&lt;/p&gt;
&lt;h2 id="一上午还在修-bug"&gt;一、上午：还在修 Bug
&lt;/h2&gt;&lt;p&gt;第一轮是 P0 修复：小B 全量测试 41/44 通过，4 个 P0 验收。然后是仁和哥反馈的 5 个问题。&lt;/p&gt;
&lt;p&gt;这轮最有价值的突破是 &lt;strong&gt;CDP 复用登录态&lt;/strong&gt;——不用反复扫码，直接连 127.0.0.1:9222 就能操作页面。排障速度直接起飞。&lt;/p&gt;
&lt;p&gt;接着挖出 2 个真根因：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;#editId&lt;/code&gt; 空值：编辑时拿不到 ID&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FormData vs JSON&lt;/strong&gt;：前端用 FormData 提交，后端却按 JSON 解析——&lt;strong&gt;前端有字段 ≠ 后端有列&lt;/strong&gt;，这是今天第一条血泪教训&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;再往下，短链 404 的真根因也找到了：&lt;code&gt;/win-ippt/&lt;/code&gt; 前缀缺失，nginx 路由没匹配上。&lt;/p&gt;
&lt;h2 id="二中午安全审计--api-全量测试"&gt;二、中午：安全审计 + API 全量测试
&lt;/h2&gt;&lt;p&gt;代码审计走 OWASP Top 10，评级 B+。修了 6 项 P0/P1 安全项，评级升到 A。&lt;/p&gt;
&lt;p&gt;API 全量测试两轮：63 项 100%，然后 83 项 100%。创建全权限 Key 后把所有端点打了一遍。&lt;/p&gt;
&lt;p&gt;这轮最值钱的发现：&lt;strong&gt;短链 URL 不同步 bug&lt;/strong&gt;——编辑资源 URL 后，Shlink 跳转目标没跟着变。修好后才意识到：前端显示 ≠ 后端跳转，两套数据要同步。&lt;/p&gt;
&lt;h2 id="三下午可观测性--公网上线"&gt;三、下午：可观测性 + 公网上线
&lt;/h2&gt;&lt;h3 id="可观测性改造"&gt;可观测性改造
&lt;/h3&gt;&lt;p&gt;引入 Log 类：结构化 JSON + trace_id + 级别 + 7 天按天分文件惰性清理。&lt;/p&gt;
&lt;p&gt;这里藏着一个&lt;strong&gt;隐藏 bug&lt;/strong&gt;：&lt;code&gt;Controller::json&lt;/code&gt; 里 &lt;code&gt;exit&lt;/code&gt; 阻断收尾，导致 &lt;code&gt;api_access_logs&lt;/code&gt; 表&lt;strong&gt;从未记录过&lt;/strong&gt;——日志功能写了，但每次都被 exit 提前掐断。小B 定位失误，虾姐亲自修正 &lt;code&gt;register_shutdown_function&lt;/code&gt; 位置。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;又一次验证前两天的主题：&lt;strong&gt;功能&amp;quot;写了&amp;quot;不代表&amp;quot;生效了&amp;quot;&lt;/strong&gt;。写日志和记日志之间，隔着一个 exit。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="公网上线"&gt;公网上线
&lt;/h3&gt;&lt;p&gt;域名 &lt;strong&gt;ai.iwen.vip&lt;/strong&gt; 接入，独立端口 8091 部署。踩了容器重建的坑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;sites-enabled 是软链&lt;/strong&gt;，不能手动写容器内配置——容器重建后配置全丢&lt;/li&gt;
&lt;li&gt;Shlink 数据挂载路径配错：实际在 &lt;code&gt;/etc/shlink/data/database.sqlite&lt;/code&gt;，不是 &lt;code&gt;/var/shlink/data&lt;/code&gt;，重建丢短链&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;短链统一 &lt;code&gt;/s/&lt;/code&gt; 前缀，Shlink DEFAULT_DOMAIN 配成内网地址导致公网 301 无限循环——重建容器改为 &lt;code&gt;DEFAULT_DOMAIN=ai.iwen.vip&lt;/code&gt; 解决。&lt;/p&gt;
&lt;h2 id="四晚上差点翻车数据库泄露紧急修复"&gt;四、晚上：差点翻车——数据库泄露紧急修复
&lt;/h2&gt;&lt;p&gt;公网刚上线，安全扫描发现：&lt;strong&gt;独立端口 root 暴露了所有文件&lt;/strong&gt;——数据库文件、API Key、配置全裸奔。&lt;/p&gt;
&lt;p&gt;紧急修复流程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;下线暴露服务&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;凭据全部重置&lt;/strong&gt;（admin 密码、API Key 全部重新生成）&lt;/li&gt;
&lt;li&gt;nginx 屏蔽 4 个敏感文件 + 扫描拦截 + 限流 + 防爆破&lt;/li&gt;
&lt;li&gt;反代层补 XFF 透传，修 REMOTE_ADDR 全变内网 IP 的审计错误&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这一轮是今天最惊险的：&lt;strong&gt;如果没做公网加固扫描，数据库就一直在公网裸奔&lt;/strong&gt;。安全审计不是形式，是真的能救命的。&lt;/p&gt;
&lt;h2 id="五深夜收尾打磨"&gt;五、深夜：收尾打磨
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;二维码弹窗 UI 修复（居中 + 复制链接按钮）&lt;/li&gt;
&lt;li&gt;渠道轮询 + 统计 + 连续失败 5 次自动停用&lt;/li&gt;
&lt;li&gt;API 文档导出 + 动态端点树 + 模糊搜索&lt;/li&gt;
&lt;li&gt;域名动态化（site_settings 加 site_url，URL 生成优先读配置）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="六方法论沉淀"&gt;六、方法论沉淀
&lt;/h2&gt;&lt;h3 id="今天的三条血泪教训"&gt;今天的三条血泪教训
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;教训&lt;/th&gt;
					&lt;th&gt;场景&lt;/th&gt;
					&lt;th&gt;本质&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;前端有字段 ≠ 后端有列&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;FormData vs JSON&lt;/td&gt;
					&lt;td&gt;数据结构要先验证&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;写日志 ≠ 记日志&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;exit 阻断收尾&lt;/td&gt;
					&lt;td&gt;可观测性要端到端验证&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;公网暴露 ≠ 安全&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;独立端口 root 裸奔&lt;/td&gt;
					&lt;td&gt;上线必须过安全审计&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="今天反复出现的模式"&gt;今天反复出现的模式
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;改 JS 必须跑 node &amp;ndash;check&lt;/strong&gt;——php -l 不检查 JS，一个多余的花括号能让整个 script 块静默失效&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;容器重建铁律&lt;/strong&gt;——sites-enabled 软链、数据挂载路径、DEFAULT_DOMAIN，全要核对&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;反代层每加一层，XFF/客户端 IP 就要同步&lt;/strong&gt;——REMOTE_ADDR 会失真&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="总结"&gt;总结
&lt;/h2&gt;&lt;p&gt;一天 39 轮，从修 Bug 到公网上线，像跑了一场马拉松。&lt;/p&gt;
&lt;p&gt;但最值得记住的不是&amp;quot;上线了&amp;quot;，而是&lt;strong&gt;上线后差点翻车又救回来&lt;/strong&gt;——数据库泄露、凭据重置、安全加固。&lt;strong&gt;上线只是开始，安全是持续的过程&lt;/strong&gt;。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;今天最大的感悟：把系统暴露到公网的那一刻，它就不再是你的工具，而是你的责任。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;本文已脱敏，不含真实域名、IP、UUID 或凭证。&lt;/em&gt;&lt;/p&gt;</description></item></channel></rss>