我的个人网站安全加固与优化全记录
背景 #
前几天把博客从 Congo v1 升级到了 v2,页面是好看了,但也埋下了不少坑。正好想试试 Claude Code 的「在线网站分析」能力,于是就有了这次完整的整改闭环:
Claude Code 爬取线上网站 → 生成问题清单 + 整改建议 → 逐项修复验证
整个过程非常丝滑,从发现问题到全部上线,花了不到 2 小时。
第一轮:发现问题 #
用 Claude Code 打开我的博客首页,不到 1 分钟就输出了一份非常精准的问题清单,甚至带上了修复优先级。
🚨 High Priority #
首页 meta description 为空
- Hugo 模板逻辑有问题,首页 front matter 的 description 没被正确读取
- 影响 SEO,搜索引擎抓取不到正确描述
家教页推荐徽章位置错误
- 「推荐」徽章在高中 ¥120 卡片上,而不是高三 ¥150
价格卡片 CSS 渲染错乱
- 课程设计模块颜色、排版都有问题
⚠️ Medium Priority #
About 页图片占位位置错误
- 顺序是「标题 → 图片占位 → 介绍语」,应该是「标题 → 介绍语 → 图片占位」
首页「现在在做」卡片不可点击
- 三个卡片分别应该跳转到安全研究、SecurityClaw 专题、量化页面
缺少自定义 404 页面
- 访问不存在的路径时返回默认 404,体验很差
🔍 优化建议 #
- 博客单篇文章加右侧浮动 TOC
- 长文没有目录,阅读体验不好
- 补充安全响应头
- HSTS / CSP / Permissions-Policy / 隐藏 Server 头
- 检查 sitemap 空条目
- Hugo 生成的 sitemap 可能包含空
<url>标签
- Hugo 生成的 sitemap 可能包含空
第二轮:逐项修复 #
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 + 本地开发代理 的工作流有了更深的感受:
Claude Code 当自动化测试:它能像真实用户一样浏览网站,发现各种视觉 bug 和功能缺陷,比我自己一页页翻高效太多
Hermes 当执行代理:拿到整改清单后,改 Caddyfile、改 Hugo 模板、构建部署、curl 验证,全程不用我动手
验证闭环很重要:每改完一项立刻用 curl 验证,避免「以为修好了实际上没生效」的尴尬
整个过程就像有个自动化测试团队 + 运维团队,我只需要看报告就行。这种开发体验真的会上瘾。
🌐 最终成果:https://tttjhgan.top