读书笔记: Google系统架构解密
推荐序一 xvii
推荐序二 xix
对本书的赞誉 xxi
序一 xxiii
序二 xxv
前言 xxvii
第一部分 入门资料
第1章 安全性与可靠性的交集 3
1.1 从密码和电钻谈起 3
1.2 可靠性与安全性:设计注意事项 4
1.3 机密性、完整性、可用性 5
CIA 是指 confidentiality(机密性)、integrity(完整性)和 availability(可⽤性)。
1.3.1 机密性 5
1.3.2 完整性 5
1.3.3 可用性 6
1.4 可靠性与安全性:共性 6
1.4.1 隐形 6
1.4.2 评估 7
1.4.3 简洁性 7
1.4.4 演变 7
1.4.5 弹性 8
1.4.6 从设计到生产 9
1.4.7 调查系统和日志 9
1.4.8 危机响应 9
1.4.9 恢复 10
1.5 小结 10
第2章 了解攻击者 11
2.1 攻击者动机 12
2.2 攻击者画像 13
2.2.1 业余爱好者 13
2.2.2 漏洞研究人员 13
2.2.3 黑客活动家 14
2.2.4 犯罪分子 14
2.2.5 自动化和人工智能 15
2.2.6 内部人员 15
2.3 攻击者方法论 19
2.3.1 威胁情报 19
2.3.2 网络杀伤链 20
2.3.3 TTP 20
2.4 风险评估注意事项 21
2.5 小结 21
第二部分 设计系统
第3章 示例分析:安全代理 25
3.1 生产环境中的安全代理 25
3.2 Google工具代理 27
3.3 小结29
第4章 设计中的权衡 30
4.1 设计目标和要求 31
4.1.1 特性需求 31
特性需求,也叫作功能需求。
关键需求是对产品或服务⾄关重要的特性需求 的⼦集。如果设计不能满⾜关键需求或关键⽤户故事,那么就没有可 ⾏的产品。
4.1.2 非功能性需求 31
些⾮功能性需求与我们的关注点(安全性和可靠性)相关
4.1.3 功能与涌现特性 32
4.1.4 案例:Google的设计文档 33
4.2 需求平衡 34
4.3 处理紧张局势和统一目标 37
4.3.1 案例:微服务和Google Web应用程序框架 37
4.3.2 统一涌现特性的需求 39
4.4 初始速度和持续速度 39
4.5 小结 41
第5章 最小特权设计 42
5.1 概念和术语 43
5.1.1 最小特权 43
5.1.2 零信任网络 43
5.1.3 零接触 43
5.2 基于风险的访问分类 43
5.3 最佳实践 44
5.3.1 API功能最小化 45
5.3.2 Breakglass机制 47
这个概念源于⽕警警报机制,指引⽤户“在紧急情况下打碎玻 璃”以此触发警报。Breakglass 机制提供了紧急情况下完全绕开授权机 制访问系统的能⼒。
5.3.3 审计 47
审计主要⽤于检测不正确的授权,包括系统运营⼈员滥⽤职权、 外部⼈员泄露⽤户凭据或流氓软件对另⼀个系统进⾏出乎意料的操 作。
5.3.4 测试和最小特权 49
5.3.5 诊断被拒绝的访问 50
5.3.6 优雅失败和Breakglass机制 51
5.4 工作案例:配置分发 51
5.4.1 基于OpenSSH实现的POSIX API 52
5.4.2 软件更新API 52
5.4.3 自定义OpenSSH ForceCommand 53
5.4.4 自定义HTTP接收器(边车) 53
5.4.5 自定义HTTP接收器(内置) 53
5.4.6 权衡取舍 53
5.5 一种用于认证和授权决策的策略框架 54
认证(名词):验证⽤户或进程的⾝份。
授权(名词):评估来⾃特定认证⽅的请求是否应该被允 许。
5.5.1 使用高级授权控件 55
5.5.2 投入广泛使用的授权框架 55
5.5.3 避免潜在的陷阱 56
5.6 高级控制 56
5.6.1 MPA 56
5.6.2 3FA 57
5.6.3 业务依据 58
5.6.4 临时访问 59
5.6.5 代理 59
5.7 权衡和冲突 59
5.7.1 增加了安全复杂性 60
5.7.2 对合作商及公司文化的影响 60
5.7.3 影响安全性的质量数据和系统 60
5.7.4 对用户工作效率的影响 60
5.7.5 对开发复杂性的影响 60
5.8 小结 61
第6章 面向易理解性的设计 62
本书中对系统易理解性的定义是,有相关技术背景的⼈员能够准确、 ⾃信地解释以下两点:
- 系统运⾏时的⾏为;
- 系统的不变性约束条件,包括安全性和可⽤性。
6.1 为什么易理解性很重要 62
更具体地说,⼀个容易理解的系统 有以下⼏点好处。
- 降低安全漏洞或弹性故障的可能性。⽆论什么时候更改系统或者软件组件(⽐如添加功能、修复缺陷 或配置变更),都可能存在意外引⼊新的安全漏洞或者削弱系统弹性的⻛ 险。
- 促进有效的事件响应。在事件发⽣期间,响应⼈员能否快速准确地评估损失、控制事 件、识别根本原因并解决问题,这是⾄关重要的。
- 增强对于系统安全态势的断⾔的信⼼。关于系统安全性的断⾔通常⽤不变量来表⽰。不变量指系统所有 可能的⾏为必须具备的属性。换句话说,系统在对恶意输⼊做出响应时的⾏为不得违反所需的安全 属性。
6.1.1 系统不变量 63
6.1.2 分析不变量 64
6.1.3 心智模型 65
6.2 设计易理解的系统 65
6.2.1 复杂性与易理解性 65
6.2.2 分解复杂性 66
6.2.3 集中负责安全性和可靠性需求 67
6.3 系统架构 67
6.3.1 易于理解的接口规范 68
1.优先选⽤解释空间更少的窄接⼝
服务可以使⽤许多不同的模型和框架来开放接⼝,举⼏个例⼦:
- 基于 RESTful HTTP 和 JSON 的 OpenAPI
- gRPC
- Thrift
- W3C Web Services(XML/WSDL/SOAP)
- CORBA
- DCOM
6.3.2 易于理解的身份、认证和访问控制 69
6.3.3 安全边界 74
6.4 软件设计 78
6.4.1 使用应用程序框架满足服务需求 78
6.4.2 理解复杂的数据流 79
6.4.3 考虑API的可用性 81
6.5 小结 83
第7章 适应变化的设计 84
7.1 安全变更的类型 85
7.2 变更中的设计 85
7.3 让发布更容易的架构决策 86
7.3.1 让依赖项保持最新并频繁重建86
7.3.2 用自动化测试让发布更频繁86
7.3.3 使用容器 87
7.3.4 使用微服务 87
7.4 不同的变更:不同的速度与不同的时间线 89
7.4.1 短期变更:零日漏洞 90
7.4.2 中期变更:改善安全态势 92
7.4.3 长期变更:外部需求 94
7.5 难点:计划调整 96
7.6 不断扩大的范围:心脏滴血漏洞 97
7.7 小结 98
第8章 弹性设计 99
好的系统设计应该包括弹性的规划:系统抵御攻击和承受异 常情况(给系统带来压⼒并影响可靠性的场景)的能⼒。
弹性与恢复性密切相关,但恢复性关注的是系统损坏之后⾃我修 复的能⼒,⽽弹性则意味着设计出经得起破坏的系统。
8.1 弹性设计原则 100
8.2 纵深防御 100
纵深防御通过建⽴多层防御边界来保护系统。因此,攻击者对系 统了解有限,也就更难以成功利⽤漏洞。
8.2.1 特洛伊木马 100
3.执⾏
如果防御者将特洛伊⽊⻢包围起来,限制了他们的暴露 环境,攻击者将更难在不被注意的情况下离开藏⾝之处。⽹络战 中将这种战术称为沙盒(将在 8.2.2 节的“运⾏时层”进⾏更详细的 描述)。
8.2.2 Google App Engine分析 102
8.3 控制降级 104
8.3.1 区分故障成本 105
8.3.2 部署响应机制 107
8.3.3 负责任的自动化 109
8.4 控制爆炸半径 111
如今,提⾼安全性的常⻅⽅法是对⽹络进⾏分段,并将每个⽹段 的访问权限授予特定类别的⽤户或服务。可以通过将虚拟局域⽹ (VLAN)与⽹络 ACL 配合使⽤来达到此⽬的
8.4.1 角色分离 112
8.4.2 位置分离 113
8.4.3 时间分离 115
8.5 故障域和冗余 115
8.5.1 故障域 116
8.5.2 组件类型 117
8.5.3 控制冗余 119
8.6 持续验证 120
8.6.1 验证关键区域 121
8.6.2 验证实践 122
8.7 实践建议:着手点 124
8.8 小结 125
第9章 面向恢复性的设计 127
9.1 要恢复什么 128
9.1.1 随机错误 128
9.1.2 意外错误 128
9.1.3 软件错误 128
9.1.4 恶意行为 129
9.2 恢复机制的设计原则 129
9.2.1 面向快速恢复的设计(受政策监督) 129
9.2.2 限制对外部时间观念的依赖 132
9.2.3 回滚所代表的安全性和可靠性间的权衡 133
9.2.4 使用显式吊销机制 139
9.2.5 了解精确到字节的预期状态 142
9.2.6 面向测试和持续验证的设计 145
9.3 紧急访问 146
9.3.1 访问控制 147
9.3.2 通信 148
9.3.3 响应人员的习惯 148
9.4 预期外的收益 149
9.5 小结 149
第10章 缓解拒绝服务攻击 150
10.1 攻守双方的策略 150
10.1.1 攻方的策略 151
因为单台机器很少能使⼀项⼤型服务中断(通常由多台服务器⽀ 撑),所以孤注⼀掷的攻击者会开发⼯具来融合多台机器的⼒量,这 就是所谓的分布式拒绝服务(distributed denial- of-service, DDoS)攻 击。
10.1.2 守方的策略 152
10.2 面向防御的设计 152
10.2.1 具有防御能力的架构 152
10.2.2 使服务具备防护能力 154
10.3 缓解攻击 154
10.3.1 监控与告警 154
10.3.2 优雅降级 155
10.3.3 DoS防护系统 155
10.3.4 有策略的响应 156
10.4 应对源于服务本身的“攻击” 157
10.4.1 用户行为 157
10.4.2 客户端重试行为 158
10.5 小结 159
第三部分 实现系统
第11章 案例分析:设计、实现和维护一个受信任的公共CA 163
11.1 受信任的公共CA的背景 163
11.2 为什么需要受信任的公共CA 164
11.3 自建还是购买CA 165
11.4 设计、开发和维护过程中的考虑 165
11.4.1 选择编程语言 166
11.4.2 复杂与简明 166
11.4.3 保护第三方和开源组件 167
11.4.4 测试 167
11.4.5 CA密钥材料的弹性 168
11.4.6 数据验证 168
11.5 小结 169
第12章 编写代码 170
12.1 框架级安全性和可靠性保证措施 171
12.1.1 使用框架的好处.172
12.1.2 案例:用于创建RPC后端的框架 172
12.2 常见安全漏洞 176
12.2.1 SQL注入漏洞:TrustedSqlString 177
12.2.2 预防XSS漏洞:SafeHtml 178
12.3 评估和构建框架的经验 179
12.3.1 用于常见任务的简单、安全、可靠的库 180
12.3.2 部署策略 181
12.4 简洁性有助于提升代码的安全性和可靠性 182
12.4.1 避免多层嵌套 182
12.4.2 消除YAGNI类代码 183
12.4.3 偿还技术债务 184
12.4.4 重构 184
12.5 默认安全性和可靠性 185
12.5.1 选择合适的工具 185
12.5.2 使用强类型 186
12.5.3 检查代码.188
12.6 小结 189
第13章 代码测试 190
13.1 单元测试 190
13.1.1 编写有效的单元测试 191
13.1.2 编写单元测试的时机 191
13.1.3 单元测试对代码的影响 192
13.2 集成测试 193
13.3 动态程序分析 194
编译期间,ASan 添加某些指令,以便在提供的 Sanitizer 运⾏时中设置回调。运⾏时会维护有关程序执⾏的元数据,如 访问哪些内存地址是有效的。ASan 使⽤影⼦内存来记录程序将访问的 给定字节是否安全,并在程序试图读取或写⼊该字节时使⽤编译器插 ⼊的指令来检查影⼦内存。它还提供⾃定义内存分配和释放(malloc 和 free)功能。例如,malloc 函数在返回的请求内存区域之前和之 后⽴即分配额外内存。创建⼀个缓冲区存储区域,从⽽允许 ASan 报告 缓冲区上溢和下溢,并提供错误细节和位置等精确信息。要实现这⼀ 效果,ASan 会将这些区域(也称为红⾊区域)标记为污染状态。类似 地,ASan 会将已释放的内存标记为污染状态,从⽽使捕获释放后重引 ⽤(use-after-free)漏洞变得轻⽽易举。
13.4 模糊测试 197
13.4.1 模糊引擎的工作原理 197
13.4.2 编写有效的模糊测试驱动程序 200
13.4.3 示例fuzzer 201
13.4.4 持续模糊测试 204
13.5 静态程序分析 205
13.5.1 自动代码检查工具 205
13.5.2 如何将静态分析集成至开发工作流中 209
13.5.3 抽象解释 211
13.5.4 形式化方法 213
13.6 小结 213
第14章 部署代码 214
14.1 概念和术语 214
14.2 威胁建模 216
14.3 最佳实践 217
14.3.1 强制做代码审查 217
14.3.2 依赖自动化 218
14.3.3 验证工件,而不仅仅是人 218
14.3.4 将配置视为代码.219
14.4 基于威胁建模做安全加固 220
14.5 高级缓解策略 222
14.5.1 二进制文件来源 222
14.5.2 基于来源的部署策略 224
14.5.3 可验证的构建 225
14.5.4 部署阻塞点 230
14.5.5 部署后验证 231
14.6 实用建议 232
14.6.1 一步步来 232
14.6.2 提供可操作的错误消息 233
14.6.3 确保来源信息明确 233
14.6.4 创建明确的策略 233
14.6.5 引入Breakglass机制 234
14.7 重温基于威胁建模部署安全措施 234
14.8 小结 234
第15章 调查系统 235
15.1 从调试到调查 236
15.1.1 案例:临时文件 236
15.1.2 调试技巧 237
15.1.3 当陷入困境时该怎么办 243
15.1.4 协同调试:一种教学方法 246
15.1.5 安全调查与系统调试间的差异 246
15.2 收集恰当、有用的日志 247
15.2.1 将日志设计为不可变的 248
15.2.2 考虑隐私要素 249
15.2.3 确定要保留哪些安全相关的日志 249
15.2.4 日志记录成本 252
15.3 可靠、安全的调试访问 253
15.3.1 可靠性 253
15.3.2 安全性 253
15.4 小结 254
第四部分 维护系统
第16章 防灾规划 257
16.1 “灾难”的定义 257
16.2 动态灾难响应策略 258
16.3 灾难风险分析 259
16.4 建立事件响应团队 259
16.4.1 确定团队成员和角色 260
16.4.2 制订团队章程 261
16.4.3 建立严重性和优先级模型 262
16.4.4 确定与IR团队合作的运营参数 262
16.4.5 制订响应计划 263
16.4.6 创建详细的行动手册 264
16.4.7 确保访问和更新机制就位 264
16.5 在事件发生前预先安排系统和人员 264
16.5.1 配置系统 265
16.5.2 培训 265
16.5.3 流程和程序 266
16.6 测试系统和响应计划 266
16.6.1 审计自动化系统 267
16.6.2 开展非侵入式桌面演练.267
16.6.3 在生产环境中测试响应 268
16.6.4 红队测试 270
16.6.5 评估响应 270
16.7 Google的案例 271
16.7.1 具有全球影响的测试 271
16.7.2 DiRT演习测试紧急访问 271
16.7.3 行业级漏洞 271
16.8 小结 272
第17章 危机管理 273
17.1 是否存在危机 274
17.1.1 事件分诊 274
17.1.2 入侵与缺陷 275
17.2 指挥事件 276
17.2.1 第一步:不要惊慌 276
17.2.2 开展响应 277
17.2.3 组建自己的事件团队 277
17.2.4 OpSec 278
17.2.5 牺牲好的OpSec实践换取更大的利益 280
17.2.6 调查过程 280
17.3 控制事件 283
17.3.1 并行处理事件 283
17.3.2 移交 284
17.3.3 士气 286
17.4 沟通 287
17.4.1 误解 287
17.4.2 拐弯抹角 287
17.4.3 会议 288
17.4.4 让合适的人了解合适的细节 289
17.5 整合回顾 290
17.5.1 分诊 290
17.5.2 宣布事件 290
17.5.3 沟通和OpSec 290
17.5.4 开始处理事件 291
17.5.5 移交 291
17.5.6 交还事件调查工作 291
17.5.7 准备沟通和补救 292
17.5.8 结束 292
17.6 小结 293
第18章 恢复和善后 294
18.1 恢复调度 295
18.2 恢复时间线 296
18.3 恢复计划 297
18.3.1 确定恢复范围 297
18.3.2 恢复过程的考虑因素 298
18.3.3 恢复检查清单 301
18.4 启动恢复 302
18.4.1 隔离资产 302
18.4.2 系统恢复和软件升级 303
18.4.3 数据过滤 304
18.4.4 恢复数据 304
18.4.5 更换凭据和密钥 305
18.6 恢复之后 306
18.7 示例 308
18.7.1 被入侵的云实例 308
18.7.2 大规模钓鱼攻击 309
18.7.3 需要复杂恢复工作的、有针对性的攻击 310
18.8 小结 311
第五部分 组织与文化
第19章 案例研究:Chrome安全团队 315
19.1 背景和团队发展史 315
19.2 安全是团队的职责 317
19.3 帮助用户安全地浏览Web页面 318
19.4 速度很重要 319
19.5 设计纵深防御机制 319
19.6 保持透明,让社区参与进来 320
19.7 小结 320
第20章 理解角色和责任 321
20.1 谁为安全性和可靠性负责 322
20.1.1 专家的作用 322
20.1.2 了解安全专业知识 324
20.1.3 资格认证和学术教育 325
20.2 将安全性整合到组织中 325
20.2.1 嵌入安全人员和安全团队 327
20.2.2 案例:Google的嵌入式安全 327
20.2.3 特殊的团队:蓝队和红队 329
通常使⽤不同的颜⾊来标记安全团队,以表⽰他们不同的职责 。
这个配色方案源自美国军方。
蓝队主要负责评估、加固软件和基础设施,还负责检测和管控, 并在发⽣攻击的情况下进⾏恢复⼯作。组织内任何从事防御⼯作的员 ⼯都是蓝队成员,其中包括负责系统安全性和可靠性的⼈。
红队负责进攻性安全演习:模拟真实的攻击者⼿法,开展端到端 攻击。这些演习能暴露组织的防御弱点,并能测试发现和防御攻击的 能⼒。
20.2.4 外部研究者 330
20.3 小结 332
第21章 建立安全可靠的文化 333
21.1 定义健康的安全性和可靠性文化 334
21.1.1 默认的安全性和可靠性文化 334
21.1.2 评审文化 335
21.1.3 意识文化 336
21.1.4 说“是”的文化 339
21.1.5 接受必然性的文化 340
21.1.6 可持续发展文化 340
21.2 通过最佳实践改变文化 342
21.2.1 对齐项目目标和激励参与者 342
建立信任很难,失去却很容易。
21.2.2 通过风险规避机制减少恐惧 343
- ⾦丝雀测试和灰度发布。 通过向⼩范围的⽤户或系统发布重⼤变更来减少担忧。
- 狗粮(dogfood)。通过向⽤户展⽰⾃⼰不担⼼⾃⼰做的变更,可以传递任何特 定更改对稳定性和⽣产⼒不会有影响的信⼼。狗粮(亦称“吃你⾃⼰的 狗粮”)是指在影响他⼈之前应⽤变更。
- 先可选,再强制
- 渐进式收紧
21.2.3 使安全兜底措施成为常态 344
21.2.4 提高生产力和可用性 344
如果⼈ 们认为新的控制措施减缓了发展和创新的步伐,那么他们可能会认为 采纳变更会对组织产⽣负⾯影响。
- 构建透明功能。我们讨论了如何通过使⽤默认安全的 API、框架和库来减轻开发⼈员在安全性和可靠性⽅⾯的负担。
- ⾃⾏注册与⾃⾏判断门户。我们发现公开投票是⼀种令⼈满意的管控⽅式。
21.2.5 多沟通,保持透明 345
21.2.6 怀抱同理心 346
21.3 说服领导层 347
21.3.1 了解决策过程 347
21.3.2 为变革立案 348
21.3.3 选择自己的战场 349
21.3.4 升级和问题解决 349
21.4 小结 350
总结 351
附录 灾难风险评估矩阵 353
作者介绍 355
封面介绍 355

浙公网安备 33010602011771号