html 一个有脉冲的静态网站:AWS 上的隐私安全访客分析 — Bernd Kuhlen
BK BERND KUHLEN所有笔记 ↗
← 返回实地笔记

掌握脉冲的静态站点:AWS 上的隐私安全访客分析

静态网站非常平静。没有等待修补的应用程序服务器,没有数据库连接池需要耗尽,也没有必须全天候保持清醒状态的公共 API。浏览器要求提供文件;内容分发网络会返回文件。

这种简单性为这个作品集提出了一个有趣的问题:在不将网站变成动态应用程序或发布本应保密的信息的情况下,我能否展示网站的读取位置以及请求流量如何随着时间的推移而变化?

答案变成了一个由CloudFront访问日志、CloudWatch、Lambda、EventBridge和S3中的单个JSON对象构建的小型数据管道。访客可以看到世界地图、国家总数、热门页面和请求率图表。他们从不接收原始日志、IP 地址、用户代理或个人浏览历史记录。

该网站保持静态。数据是在其他地方准备的,只是作为另一个静态文件到达。

一个请求路径中的架构

公共请求路径故意保持简短:

  1. 访客通过亚马逊 CloudFront 请求该网站。
  2. CloudFront 提供私有源是 S3 存储桶的缓存文件。
  3. 浏览器稍后会获取 content/public-visitors.json 就像任何其他静态资产一样。
  4. 客户端 JavaScript 渲染该匿名文档中的地图和图表。

浏览器不调用 Lambda。它不查询 CloudWatch。它没有 AWS 证书,也不能要求其他时间范围或更详细的记录。所有昂贵而敏感的工作都是在公共请求路径之外进行的。

在幕后,数据路径如下所示:

CloudFront → CloudWatch Logs → scheduled Lambda → aggregated JSON → S3 → CloudFront → browser

这种分离是关键的架构决策。操作系统可以处理详细的访问数据;发布系统仅发布用于公开展示的一小部分数据。

收集一次,少发布

CloudFront 标准日志记录版本 2 将选定的访问日志字段提供给 CloudWatch Logs 组。操作日志包含足够的信息来调查请求和状态代码,但这并不意味着所有信息都属于公共仪表板。

发布功能故意将数据简化为聚合数据:

  • 按国家/地区代码分组的成功的 HTML 页面浏览量;
  • 最常请求的 HTML 路径;
  • 根据汇总的 HTTP 状态指标得出的每分钟请求数;
  • 更新时间戳和描述每个时间范围的标签。

生成的文件不包含源 IP 地址、城市级位置、Cookie、用户代理字符串或用于识别访客旅程的序列。公开结果回答 “该网站获得了多少流量?”而不是 “谁来了?”

这也是我使用这句话的原因 页面浏览量,不是 人们。一个读者可以创建多个请求。搜索爬虫、链接预览服务、监控探测器和其他自动化可以与人流量一起出现。仪表板显示的是基础设施信号,而不是身份。

为什么 CloudWatch 坐在中间

CloudWatch 为同一活动提供了两种有用的表示形式。CloudWatch Logs Insights 可以查询结构化请求记录,以获取国家和页面汇总信息。指标筛选器计算四个 HTTP 状态系列(2xx、3xx、4xx 和 5xx),因此,CloudWatch 指标数据无需重复解析每个日志事件即可生成请求速率序列。

公共数据集提供了多种视图:

  • 过去 24 小时、7 天和 30 天的国家总数;
  • 24 小时、7 天、30 天和 12 个月的积分申请评级;
  • 更粗糙的时间段适用于更长的范围,从而使文档保持紧凑。

CloudFront 日志不是实时事件流。AWS 指出,标准日志通常在一小时内交付,而有些条目偶尔会稍后送达。这使得它们非常适合使用诚实的回顾性仪表板,而不是实时访客计数器。

计划快照而不是公共 API

EventBridge 规则每六小时调用一次发布的 Lambda。该函数运行其边界查询、请求指标系列、汇编文档并只覆盖一个 S3 密钥: content/public-visitors.json.

六小时是故意保守的。访客分析不需要逐秒刷新,每次刷新都会扫描日志数据。较短的时间间隔将产生更多的查询执行次数和更高的成本,而不会使页面变得更有用。

JSON 对象由面向重新验证的缓存标头提供。因此,在 CloudFront 仍在保护 S3 源的同时,主页可以发现更新的快照。当统计数据发生变化时,无需部署完整站点,也无需使全局缓存失效。

该快照模型具有令人愉悦的故障模式。如果查询或 Lambda 调用失败,则现有的静态文档仍然可用。仪表板可能会过时,但投资组合保持在线状态,无需等待分析管道的请求。

最低权限使爆炸半径变小

发布 Lambda 使用专用 IAM 角色。它的相关权限是故意缩小的:

  • 仅针对指定的访问日志组运行和检索查询;
  • 阅读请求率图表所需的 CloudWatch 指标;
  • 只写 content/public-visitors.json 在网站存储桶中;
  • 编写自己的执行日志。

它无法部署任意站点文件、更改 CloudFront 分配或公开 S3 存储桶。EventBridge 从特定的预定规则中获得调用此特定功能的权限。

网站存储桶本身仍然是私有的。CloudFront 使用原始访问控制向 S3 发送签名请求,这样可以防止查看者绕过分发并将存储桶视为公共文件服务器。

公共地图故意不太精确

更详细的仪表板不会自动成为更好的公共仪表板。城市标记看起来令人印象深刻,但少量计数加上精确的时间戳和已知人物就可以识别身份。国家层面的总数足以讲述该网站的全球故事,而不必假装基础设施遥测可以证明特定读者的居住地。

视觉设计强化了这种局限性。该地图按国家和排名显示了强度,而其正下方的解释则指出,请求是信号,而不是人。该界面不提供对个别事件的深入分析。

这种区别很重要,因为精美的图表会产生虚假的确定性。知识产权衍生国家是边缘平台的观察。VPN、企业网络、移动运营商、爬虫和缓存预览都使其背后的人类故事复杂化。

成本取决于扫描量,而不是视觉复杂度

地图和图表使用静态站点已经提供的代码在浏览器中呈现,因此它们的视觉复杂性不会产生服务器端渲染账单。有意义的运营成本来自于收集和保留日志、摄取指标以及使用计划查询扫描日志数据。

因此,这些控件是建筑性的,而不是装饰性的:

  • 30 天的日志保留政策可防止无限期增长;
  • 该函数每天仅运行四次;
  • 查询请求限定时间窗口,仅限必填字段;
  • 较长的图表范围使用更粗糙的指标周期;
  • 与源日志相比,发布的 JSON 文件很小。

在这个规模下,一个紧凑文档的 Lambda 执行时间和 S3 存储空间可以忽略不计。如果流量或留存率大幅增长,Logs Insights 扫描量是值得关注的组成部分。

实施教会了我什么

静态并不意味着盲目。 可观测性可以存在于静态站点旁边,而无需进入其同步请求路径。

聚合是一个安全边界。 从操作日志到公共文档的转换应是明确的、经过审查的和单向的。

足够新鲜比虚假的实时要好。 六小时快照与标准访问日志的延迟性质相匹配,避免了不必要的工作。

失败应该保留以前的真理。 过时的快照比因分析服务不可用而失败的主页更可取。

解释图表旁边的限制。 公共可视化需要有关机器人、重复请求、地理推断以及流量和人员差异的背景信息。

我什么时候会选择不同的设计

这种模式适用于流量适中、预定视图较少的个人网站。如果用户需要任意查询、经过身份验证的仪表板、二级新鲜度或大型多维数据集,我会重新考虑的。这些要求可能会证明API、专用分析商店或托管可视化平台是合理的。

对于这个投资组合,这些新增可以解决我没有的问题。一项预定功能和一份静态文档保留了最初使该网站具有吸引力的特性:攻击面小、行为可预测以及易于推理的组件。

最后的外卖

此访客仪表板中最重要的部分不是世界地图。这是它背后的边界。

详细的请求数据仍保留在操作环境中。权限最低的进程会定期将其转换为匿名聚合。该网站仅接收一个紧凑的静态快照,而浏览器会将该快照变成一个故事。

这为该部位提供了脉冲,而不会给它带来脆弱的动态心脏。

参考文献

BERND KUHLEN · 云工程实地笔记
ZH
EnglishENDeutschDEEspañolES中文ZH