网站主页已经更新,浏览器却仍然跳转到旧地址:一次缓存问题的排查记录

网站改版之后,有时会遇到一种看起来很像服务器配置错误的问题: 服务器上的主页已经更换,旧的跳转逻辑也已经取消,但访问网站根地址时,浏览器仍然自动跳转到过去使用的旧页面。由于旧页面已经被删除或停止使用,最终看到的往往是一个 404 Not Found。 这种现象很容易让人误以为 Apache、Nginx、VirtualHost 或 Rewrite 规则仍然存在问题。 实际上,问题也可能完全发生在浏览器端。 问题场景 假设网站过去采用如下结构: 根目录中的主页负责判断访问设备,然后将桌面浏览器跳转到: 移动设备则可能跳转到另外一个页面。 后来网站进行了调整,新的主页直接部署到了根地址: 因此旧的: 已经不再需要,甚至已经被删除。 服务器配置也已经更新。 但某些此前访问过网站的浏览器再次打开: 时,仍然立即进入: 随后返回 404。 此时需要先判断一个关键问题: 跳转到底发生在服务器端,还是浏览器端? 最简单的判断方法:使用隐身窗口 可以先使用浏览器的 Incognito / Private Window 打开网站根地址: 如果隐身窗口能够正常显示新主页,而普通窗口仍然跳转到旧地址,那么服务器通常已经没有问题。 问题基本可以锁定在: 浏览器缓存。 隐身窗口不会直接使用普通浏览器 Profile 中已经保存的大部分站点缓存,因此相当于进行了一次相对干净的访问测试。 这个方法非常适合快速区分: 和: 使用 Chrome DevTools 强制刷新缓存 在 Chrome 中,可以使用开发者工具强制重新请求网站资源。 操作步骤: 此时 Chrome …

Nginx 反向代理配置的拆分设计:文件名不重要,边界设计更重要

随着服务器数量和自建服务逐渐增加,Nginx 反向代理配置往往会从最初的几个 server 块,发展成一个包含大量域名、端口、证书和代理规则的超长配置文件。 这种集中式配置在规模较小时没有明显问题,但当后端主机越来越多后,维护成本会迅速上升。此时,可以采用一种更清晰的设计: 按后端主机拆分 Nginx 反向代理配置,一台主机对应一个配置文件。 这不仅是文件整理方式的变化,更是一种配置管理思想的变化。 一、Nginx 是否关心配置文件的名字 Nginx 通常不关心配置文件叫什么名字,它真正关心的是主配置中的 include 指令。 例如: 这条规则表示: 加载指定目录中所有以 .conf 结尾的文件。 因此,下面这些文件名都可以被加载: Nginx 不会因为文件名中出现了 host、proxy、storage 或其他词语,就赋予文件特殊功能。 文件名主要是给管理员阅读和管理使用的。 真正决定配置是否生效的是: 例如,当加载规则是: 以下文件通常不会被加载: 因为它们并不是以 .conf 结尾。 这也是一种很实用的配置停用方式:保留文件,但通过修改后缀让它退出加载范围。 二、为什么要按后端主机拆分 一个反向代理节点可能同时代理多台后端服务器。 例如: 如果所有配置都写在同一个文件中,随着服务数量增加,文件会逐渐变成: 不同主机、不同服务和不同证书混在一起,查找和修改都容易出错。 按后端主机拆分后,目录结构可以变成: 每个文件只负责一台后端主机。 例如: 只包含所有转发到主站服务器的域名和服务。 只包含备份管理系统的入口。 只包含转发到另一台独立服务器的域名和端口。 这种设计符合一个重要原则: 将具有相同变化原因的配置放在一起,将变化原因不同的配置分开。 某台后端服务器迁移、关机、更换地址或调整服务端口时,只需要检查对应的一个文件,而不必在数百行配置中寻找所有相关规则。 三、这种设计的核心思想 1. 高内聚 …

让公网 URL 与服务器目录解耦:一套低风险的 Apache 多应用路由重构方法

前言 一台 Web 服务器长期运行后,常会逐渐积累多个独立应用。最初部署时,为了省事,很多应用直接依赖站点根目录发布:磁盘目录叫 tool-alpha,公网地址也自然变成 /tool-alpha/。 这种方式能够工作,但公网 URL 与磁盘目录形成了不必要的一一绑定。项目目录一旦带有内部命名、历史命名或技术实现含义,公网地址也会跟着暴露;以后想调整 URL,又容易误以为必须移动项目目录。 更稳妥的做法是: 保持应用目录和程序结构不动,只在 Web 服务器配置层重新定义公网入口。 本文记录一次经过审计、分层验证和安全切换的实践。示例中的域名、主机名、应用名、目录、端口和配置文件名均为虚构内容。 一、改造前的典型结构 示例环境有两层 Web 服务: 公网客户端   ↓ HTTPSedge-gateway(Nginx)   ↓ HTTP 反向代理web-node(Apache)   ↓多个静态、PHP 和本地后端应用 网关层使用通用代理规则,将普通路径原样转发给后端 Apache: location / {    proxy_pass http://10.0.0.20;} 后端 Apache 的站点根目录是: /srv/web/ 多个应用原先直接按目录名对外发布: /srv/web/app-alpha/   → /app-alpha//srv/web/app-beta/   → /app-beta//srv/web/app-gamma/ …

多个域名共用同一台 Nginx 反向代理服务器的 443 端口

本文中的域名、主机名、IP 地址、端口、文件路径、脚本名称和服务名称均为虚构示例,已与实际环境完全分离。 一、需求背景 在家庭服务器、小型实验室或自托管环境中,常见需求包括: 例如,存在两套独立域名: 这些域名可以全部使用同一个公网 IP,并共同通过标准 HTTPS 端口 443 访问。 核心技术包括: 二、整体架构 示例网络结构如下: 路由器只需保留一条主要的 HTTPS 转发: 外部访问地址保持为标准形式: 无需在 URL 后附加内部应用端口。 三、为什么多个域名能够共用 443 HTTPS 客户端在 TLS 握手阶段通常会携带目标域名,这项机制称为: Nginx 接收到连接后,可以根据客户端请求的域名选择对应的: 因此,以下请求虽然全部进入同一个地址: 仍可被 Nginx 分别处理: 从公网看,所有服务都使用标准 HTTPS;从局域网看,每个域名可以对应不同的主机、端口和应用。 四、Nginx 配置示例 假设域名和后端关系如下: 可以配置四个独立的 server 块。 主域名和 www 子域名 管理子域名 API 子域名 其他应用子域名 五、不同域名可以使用不同证书 多个域名共用同一个 …

让自动化代理安全连接安卓手机:从 SSH 误区到无线 ADB 的完整实践

一、需求背景 在家庭网络中运行了一台常驻服务器,并在服务器上部署自动化代理。希望代理能够连接安卓手机,检查系统状态、读取输入法配置、收集日志,并在明确授权的情况下完成部分设置调整。 最初容易想到的是 SSH,因为服务器管理通常都依赖 SSH。但安卓手机并不是普通 Linux 服务器,直接照搬桌面 Linux 的远程管理方式,会遇到权限、应用沙箱和后台限制等问题。 因此,首先需要区分三类工具: 这三者的用途完全不同。 二、SSH 客户端不能让服务器反向进入手机 手机上常见的 SSH 工具,多数只是 SSH 客户端。 它们适合以下方向: 例如在外出时,用手机登录家里的服务器,查看服务状态或执行维护命令。 但自动化代理连接手机需要的是反方向: SSH 客户端本身不会在手机上监听端口,因此不能让服务器主动登录手机。 如果确实希望通过 SSH 控制手机,需要在手机上另外安装能够提供 sshd 的环境,例如 Termux,并在其中安装 OpenSSH。 这种方式适合: 但它不能自动突破 Android 应用沙箱,也不能直接读取其他应用的内部私有目录。 三、Termux SSH 与无线 ADB 的区别 Termux SSH 的控制范围主要是: 无线 ADB 的控制范围则更偏向 Android 系统: 因此,如果目标是让自动化代理检查安卓系统和输入法,优先选择无线 ADB更合适。 Termux …

通过 SSH 隧道连接远程 Windows:FRP、RDP 与 Linux 客户端的组合实践

在远程维护 Windows 主机时,常见方案包括 RustDesk、AnyDesk、直接暴露 RDP、VPN,以及通过 SSH 隧道转发 RDP。 其中一种兼顾安全性、清晰度和使用便利性的方案是: 这种结构不需要把 Windows 的 RDP 端口直接暴露到公网,同时仍然可以获得原生 RDP 较高的画质、较低的带宽占用和良好的剪贴板体验。 一、整体结构 假设存在三台设备: 远程 Windows 位于内网,没有公网 IP。Windows 上运行 FRP 客户端,主动连接公网中转服务器上的 FRP 服务端。 FRP 已经建立了一条 SSH 映射: 因此,在 Linux 上可以通过下面的方式登录远程 Windows: 这里连接的虽然是公网中转服务器的地址和端口,但最终进入的是远程 Windows 的 OpenSSH 服务。 在此基础上,再增加一层 SSH 本地端口转发: 最终链路如下: 需要特别注意: FRP 映射的仍然只是 SSH,并没有把 RDP 直接暴露到公网。 …

把 DNS-01 做成一个真正可用的 Web 工具:从命令行脚本到安全的证书申请平台

为域名申请 HTTPS 证书时,HTTP-01 往往是最省事的方式。但在一些环境中,DNS-01 更合适: DNS-01 的基本原理很简单:证书机构要求申请者在指定域名下添加一条 TXT 记录,查询到正确值后,即可确认申请者拥有该域名的 DNS 控制权。 Certbot 已经能够在命令行中完成这一流程,但命令行操作并不适合所有用户。尤其是在申请根域名、多个子域名和通配符证书时,TXT 记录的管理、验证顺序、失败恢复和证书下载都会迅速变得复杂。 因此,一个围绕 DNS-01 构建的 Web 工具,价值并不在于“把命令搬到网页上”,而在于把整个异步验证过程变成一个安全、清晰、可恢复的状态机。 本文已对域名、主机、目录、端口、服务名、接口路径、文件名和部署拓扑进行抽象处理,不包含实际生产环境中的可定位信息。 一、工具的目标是什么 这个工具面向无法或不愿直接操作 Certbot 命令行的用户。 用户只需要完成几件事: 系统负责: 二、为什么不能只是给 Certbot 套一个表单 最简单的实现似乎是: 这种设计很快就会遇到问题。 Certbot 的 DNS-01 流程需要等待用户手动修改 DNS。这个过程可能持续几分钟,也可能更久。如果 HTTP 请求一直保持连接: 正确的设计应该是: 也就是说,Web 请求只负责触发和查询,不能承担整个证书申请生命周期。 三、整体架构 该工具采用常见的多层 Web 架构: 应用进程只监听本机回环地址,不直接暴露给局域网或公网。 外部入口使用现有网站下的一个应用子路径,而不是单独建立新域名。这样可以复用既有的 HTTPS 入口、访问控制和反向代理体系。 真实部署中,外部路径、内部端口、配置文件和服务名称都应视为敏感运维信息,不应出现在公开文章、截图、错误页面或前端源码中。 …

DNS-01 证书验证原理:为什么证书可以在另一台主机上申请

在部署 HTTPS 时,常见做法是在网站服务器上直接运行 Certbot,并通过 HTTP 或 HTTPS 端口完成域名验证。 但在一些网络环境中,网站服务器可能无法稳定访问证书颁发机构,也可能不方便开放 80 或 443 端口。此时,可以将证书申请过程放到另一台网络条件更好的主机上,再通过 DNS TXT 记录证明域名控制权。 这种方式称为 DNS-01 验证。 本文介绍 DNS-01 的工作原理,以及为什么域名、网站服务器和证书申请主机可以相互独立。 一、证书申请实际上在验证什么 申请 HTTPS 证书时,证书颁发机构最关心的问题不是: 证书申请程序运行在哪台服务器上? 而是: 申请者是否真正控制这个域名? 只要能够证明对域名拥有控制权,证书就可以在任意一台能够连接证书颁发机构的计算机上申请。 例如,可以存在如下架构: 这三者不需要处于同一台机器,也不需要处于同一网络或同一国家。 二、DNS-01 验证涉及的角色 DNS-01 验证通常涉及四个角色。 1. 域名 例如: 域名本身只是一个名称,由 DNS 系统负责解析。 2. 权威 DNS 服务器 权威 DNS 保存该域名的正式解析记录,例如: DNS-01 …

在边缘节点上复刻服务器邮件通知环境:Postfix 本机中继方案实践

背景 在多台服务器和个人设备组成的运维环境中,系统通知邮件是一项非常基础但重要的能力。备份任务、定时任务、系统服务、自动化脚本和监控程序,都可能需要在异常发生时主动发出通知。 已有几台系统已经具备稳定的本机邮件发送能力。这些系统并不直接对外提供邮件服务,也不负责接收邮件,而是通过本机邮件程序把通知交给 Postfix,再由 Postfix 中继到外部 SMTP 服务器。新的边缘节点也需要具备同样的能力,以便后续承载系统通知、自动化任务提醒和本机代理程序通知。 目标不是搭建完整邮件服务器,而是搭建一个安全、轻量、统一的本机发信环境。 目标设计 最终目标如下: 该方案具备几个特点: 既有系统方案盘点 在正式搭建新节点之前,先对已有系统进行了只读检查。检查对象包括两类服务器节点和一台桌面工作站。 检查重点包括: 盘点结果显示,已有几台系统虽然发行版不同,但实际发信路径已经收敛到同一种思路: 其中,Debian/Ubuntu 系系统使用 hash:/etc/postfix/… 类型的 Postfix 映射文件;Arch 系系统则使用 lmdb:/etc/postfix/… 类型的映射文件。这一点非常重要,因为不同发行版的 Postfix 默认映射类型可能不同,不能直接照抄。 新节点是 Ubuntu 系统,因此更适合复刻 Debian/Ubuntu 系的 Postfix hash 方案,而不是照搬 Arch 系的 lmdb 方案。 为什么选择 Postfix,而不是 msmtp 轻量脚本发信可以使用 msmtp,但如果目标是让整个系统具备统一发信能力,Postfix 更合适。 原因包括: 因此,新节点采用: 而不是: 安全边界 该方案的安全边界非常明确: …

一次便携式 Linux 设备 Wi-Fi 与 USB 共享网络冲突的排查与修复

背景 某台便携式 Linux 设备同时具备两种联网方式: 系统中原本有几类自定义辅助脚本: 其中,连接脚本用于扫描并连接 Wi-Fi,断开脚本用于手动断开 Wi-Fi。系统本身则启用了 dhcpcd,用于统一管理 DHCP、IP 地址、DNS、默认路由和 metric 优先级。 最初发现的问题 一次系统自检中发现,设备上同时存在 dhcpcd 和 dhclient,并且二者都在处理同一个无线接口。 这类情况容易造成网络栈混乱: 同时还观察到: 这里的一个重要教训是:自动化代理可以帮助收集信息,但安全和网络相关结论必须回到原始命令输出核对。尤其在高权限环境下,不能让代理在未经确认的情况下直接执行修复、重启服务或修改网络状态。 需求澄清 这台设备不是固定服务器,而是便携式设备,因此网络策略与普通服务器不同。 实际需求可以概括为: 因此,不适合让 Wi-Fi 连接脚本同时负责 Wi-Fi 认证、DHCP 请求、DNS 更新和默认路由修改。更合理的分工是: 只读排查 正式修改前,先进行只读检查,重点确认当前到底有哪些网络组件在运行: 同时检查自定义脚本内容: 检查结果表明,dhcpcd 已经在系统中启用并运行,而旧版 Wi-Fi 连接脚本中仍然包含类似逻辑: 这意味着脚本在启动 Wi-Fi 认证后,又手动释放 DHCP、重新请求 DHCP,并修改默认路由。这样会与 dhcpcd 的职责重叠,形成“双网络管理器”冲突。 根因 根因不是 Wi-Fi 本身,也不是 USB …