
## 一、现象概述

在实际运维或开发中，常会遇到这样一种情况：

> **某个域名一旦部署并成功访问过 HTTPS，当证书过期或 HTTPS 被移除后，域名将很难甚至无法再通过 HTTP 正常访问。**

这并非配置错误，而是浏览器安全机制的正常表现。

---

## 二、核心原因：HSTS 机制

### 1. 什么是 HSTS

HSTS（HTTP Strict Transport Security）是一种浏览器安全策略。当服务器在 HTTPS 响应中返回以下头部时：

```http
Strict-Transport-Security: max-age=31536000; includeSubDomains
```

浏览器会在 `max-age` 指定的时间内，**强制该域名仅能通过 HTTPS 访问**。

### 2. HSTS 的关键特性

- **本地强制升级**：
  - 用户访问 `http://example.com`
  - 浏览器不会发起 HTTP 请求
  - 直接在本地升级为 `https://example.com`

- **证书失效也无法回退 HTTP**：
  - HTTPS 证书过期 ❌
  - HTTP 访问被直接拦截 ❌

- **有效期长**：
  - 常见配置为一年（31536000 秒）
  - 在有效期内，服务器端修改无效

---

## 三、最严重情况：HSTS Preload

### 1. 什么是 Preload

当使用以下配置，并被提交至浏览器厂商：

```http
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
```

该域名会被加入 **浏览器内置的 HSTS Preload List**。

### 2. Preload 的影响

- 域名被写入浏览器源码
- **首次访问即强制 HTTPS**
- 无法通过以下方式绕过：
  - 清缓存
  - 无痕模式
  - 更换网络

📌 **一旦进入 Preload 列表，域名几乎永久无法使用 HTTP。**

---

## 四、其他常见影响因素

### 1. 浏览器缓存的重定向（301 / 308）

- HTTP → HTTPS 的 301 跳转可能被浏览器长期缓存
- 相比 HSTS，此问题通常可通过清缓存或更换浏览器解决

### 2. CDN 的隐式强制策略

常见 CDN（Cloudflare、阿里云、腾讯云等）可能启用：

- Always HTTPS
- 自动 301 跳转
- 自动注入 HSTS 头

即使源站关闭 HTTPS，CDN 仍可能继续生效。

### 3. includeSubDomains 的连锁影响

启用：

```http
includeSubDomains
```

会导致：

- 主域名
- 所有子域名

全部被强制 HTTPS，影响范围极大。

---

## 五、是否还能退回 HTTP？

### 情况一：普通 HSTS（未启用 Preload）

**理论可行，但条件苛刻**：

1. 重新恢复 HTTPS（证书必须有效）
2. 返回响应头：
   ```http
   Strict-Transport-Security: max-age=0
   ```
3. 用户再次访问后，浏览器才会清除 HSTS 记录

⚠️ 若 HTTPS 已不可访问，则无法下发该头部，形成死锁。

---

### 情况二：已进入 HSTS Preload List

现实结论：

> **该域名基本只能永久使用 HTTPS**

可选方案：

- 重新申请并长期维护 HTTPS 证书（推荐）
- 提交 Preload 移除申请（流程长、数月生效）
- 更换新域名

---

## 六、工程实践建议

### 推荐做法

- 将 HTTPS 视为 **单向升级，不可逆**
- 使用自动化证书续期（certbot / acme.sh / CDN 证书）
- HSTS 配置逐步升级：
  ```http
  max-age=300
  ```
  稳定后再延长
- Preload 仅在非常确定时启用

### 应避免的行为

- 在测试环境启用 preload
- 盲目复制教程中的 includeSubDomains
- 在证书失效后直接关闭 HTTPS

---

## 七、总结

> **HTTPS + HSTS 是现代 Web 的安全基石，但一旦启用，就必须长期维护。**

对于生产域名，应提前规划证书策略和 HSTS 策略，避免因 HTTPS 不可用导致整个域名不可访问。

