1. 技术文章/

我的个人网站安全加固与优化全记录

·1541 字·4 分钟

背景 #

前几天把博客从 Congo v1 升级到了 v2,页面是好看了,但也埋下了不少坑。正好想试试 Claude Code 的「在线网站分析」能力,于是就有了这次完整的整改闭环:

Claude Code 爬取线上网站 → 生成问题清单 + 整改建议 → 逐项修复验证

整个过程非常丝滑,从发现问题到全部上线,花了不到 2 小时。


第一轮:发现问题 #

用 Claude Code 打开我的博客首页,不到 1 分钟就输出了一份非常精准的问题清单,甚至带上了修复优先级。

🚨 High Priority #

  1. 首页 meta description 为空

    • Hugo 模板逻辑有问题,首页 front matter 的 description 没被正确读取
    • 影响 SEO,搜索引擎抓取不到正确描述
  2. 家教页推荐徽章位置错误

    • 「推荐」徽章在高中 ¥120 卡片上,而不是高三 ¥150
  3. 价格卡片 CSS 渲染错乱

    • 课程设计模块颜色、排版都有问题

⚠️ Medium Priority #

  1. About 页图片占位位置错误

    • 顺序是「标题 → 图片占位 → 介绍语」,应该是「标题 → 介绍语 → 图片占位」
  2. 首页「现在在做」卡片不可点击

    • 三个卡片分别应该跳转到安全研究、SecurityClaw 专题、量化页面
  3. 缺少自定义 404 页面

    • 访问不存在的路径时返回默认 404,体验很差

🔍 优化建议 #

  1. 博客单篇文章加右侧浮动 TOC
    • 长文没有目录,阅读体验不好
  2. 补充安全响应头
    • HSTS / CSP / Permissions-Policy / 隐藏 Server 头
  3. 检查 sitemap 空条目
    • Hugo 生成的 sitemap 可能包含空 <url> 标签

第二轮:逐项修复 #

1. meta description 修复 #

问题定位:Congo 模板的 head.html 里 description 绑定逻辑有多层 fallback,但首页 content/_index.md 的 front matter 虽然写了 description,但实际渲染出来是空的。

解决:直接在 languages.zh-CN.toml 里加全局 params.description 作为最终兜底。

[params]
  description = "网络空间安全学生,专注 Web 安全、代码审计、AI Agent 安全研究,持续更新技术博客。"

2. 家教页完全重构 #

原页面用的是 Markdown 内嵌 HTML 写法,导致 CSS 类经常被转义或错乱。

改成纯 Hugo 布局模板 layouts/_default/tutoring.html

  • 价格卡片用 Tailwind 的 group + hover 状态
  • 高三卡片加琥珀色边框 + 右上角推荐徽章
  • 教学理念三卡片独立区块
  • 真实案例区块结构化
  • 联系方式与二维码占位

还顺手把所有 bg-white/50 这种带透明度的背景改成了实色,暗色模式下不再有发白割裂感。

3. 首页卡片可点击 + hover 上浮 #

原来三个卡片只是静态文本,用户想点却点不了。

<a href="{{ "/securityclaw-learning/" | relURL }}" 
   class="p-4 rounded-lg bg-neutral-100 dark:bg-neutral-800/50 
          hover:ring-2 hover:ring-primary-400/30 
          hover:-translate-y-0.5 transition-all cursor-pointer">
  <!-- 卡片内容 -->
</a>

加了 hover:-translate-y-0.5 轻微上浮效果,交互感立刻就有了。

4. 自定义 404 页面 #

layouts/404.html

{{ define "main" }}
<section class="mx-auto max-w-2xl py-20 text-center">
  <h1 class="text-6xl font-bold text-primary-500">404</h1>
  <p class="mt-6 text-xl">🛡️ 请求的资源不存在,或已被安全策略拦截。</p>
  <p class="mt-3 text-neutral-500">Attack pattern detected? 别慌,只是页面走丢了。</p>
  <a href="/" class="mt-8 inline-block px-6 py-3 rounded-lg bg-primary-500 text-white hover:bg-primary-600">返回首页</a>
</section>
{{ end }}

Caddy 配置配合

handle_errors {
    @404 expression {http.error.status_code} == 404
    rewrite @404 /404.html
    file_server
}

5. 安全响应头加固 #

直接在 Caddyfile 里加完整 header 块:

header {
    # HSTS 一年
    Strict-Transport-Security "max-age=31536000; includeSubDomains"
    
    # CSP - 静态博客够用的宽松策略
    Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'"
    
    # 禁用不需要的浏览器 API
    Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=()"
    
    X-Content-Type-Options nosniff
    X-Frame-Options DENY
    Referrer-Policy strict-origin-when-cross-origin
    
    # 隐藏 Caddy 版本
    -Server
}

第三轮:验证与验收 #

✅ 功能验证清单 #

检查项结果
meta description正确渲染
推荐徽章在高三卡片
价格卡片 hover 效果
首页卡片可点击跳转
404 页面正常返回 404
CSP 不影响 Mermaid 渲染
CSP 不影响 fuse.js 搜索
CSP 不影响主题切换
Sitemap 空条目0 个
Server 头隐藏

📝 最终修改文件 #

/etc/caddy/Caddyfile          # 安全响应头 + handle_errors
layouts/_default/tutoring.html  # 家教页纯模板重构
layouts/_default/404.html     # 自定义 404
layouts/partials/home/custom.html  # 卡片 hover 上浮
content/_index.md            # description 修正

感想 #

这次体验让我对 AI + 本地开发代理 的工作流有了更深的感受:

  1. Claude Code 当自动化测试:它能像真实用户一样浏览网站,发现各种视觉 bug 和功能缺陷,比我自己一页页翻高效太多

  2. Hermes 当执行代理:拿到整改清单后,改 Caddyfile、改 Hugo 模板、构建部署、curl 验证,全程不用我动手

  3. 验证闭环很重要:每改完一项立刻用 curl 验证,避免「以为修好了实际上没生效」的尴尬

整个过程就像有个自动化测试团队 + 运维团队,我只需要看报告就行。这种开发体验真的会上瘾。


🌐 最终成果https://tttjhgan.top