第一部分. HTTP: 网络的基础#
第 01 章. HTTP 概述#
关键词:
- MIME, URIs, URLs, URNs
- 事务:
- GET
- PUT
- DELETE
- POST
- HEAD
- 状态码
- 请求 / 响应消息:
- 起始行
- 头部
- 内容类型头
- 内容长度头
- 主体(可选,<一个空行(CRLF)> + < 主体 >)
- 连接:
- TCP/IP
- 连接、IP 地址和端口号
- 协议版本:
- 0.9
- 1.0
- 1.0+
- 1.1
- 2.0(HTTP-NG)
- 网络的架构组件
- 代理
- 缓存(网络缓存或缓存代理)
- 网关
- 隧道
- 代理(网络浏览器等)
第 02 章. URLs 和资源#
方案(如何)、主机(哪里)、路径(什么)
[<scheme>://][<user>[:<password>]@]<host>[:<port>][/<path>][;<params>][?<query>][#<frag>]
- 参数(Parameters),名称 / 值对。
- 基本 URL:
<BASE>
HTML 标签。将相对 URL 转换为绝对 URL - 扩展 URL
- 主机名扩展(
www.
.com
等) - 历史扩展
- 主机名扩展(
- 不明字符
第 03 章. HTTP 消息#
要点:
- 事务方向:入站,出站
- 消息流:上游,下游
- 消息语法
- 请求消息
<method> <request-URL> <version> <headers> <entity-body>
- 响应消息
<version> <status-code> <reason-phrase> <headers> <entity-body>
- ?
- 版本 2.22 > 2.3
- 头部续行
- 方法: GET, PUT, POST, TRACE, OPTIONS, DELETE
- UA(用户代理): UA-OS, UA-CPU 等。
- 头部
- 一般头部: Date: Tue, 3 Oct 1974 02:16:00 GMT
- 请求头部: Accept: /
- 接受头部
- 条件请求头部
- 请求安全头部
- 代理请求头部
- 响应头部: Server: Tiki-Hut/1.0
- 实体头部: Content-Type: text/html; charset=iso-latin-1
- 内容头部
- 实体缓存头部
- 扩展头部:
- 请求消息
另见
第 04 章。连接管理#
TCP 可靠数据管道
TCP 流被分段并通过 IP 数据包传输
保持 TCP 连接的整洁
一个 TCP 连接
<source-IP-address, source-port, destination-IP-address, destination-port>
- 使用 TCP 套接字编程
- s = socket(): 创建一个新的、未命名的、未连接的套接字。
- bind(s, ): 将本地端口号和接口分配给套接字。
TCP 性能考虑
- HTTP 事务延迟
- 性能关注领域
- 延迟确认
- TCP 慢启动
- Nagle 算法和 TCP_NODELAY
- TIME_WAIT 积累和端口耗尽
- 串行事务延迟
并行连接
- 并行连接可能使页面加载更快
- 并行连接并不总是更快
- 并行连接可能 “感觉” 更快
持久连接
持久连接与并行连接
HTTP/1.0 + 保持活动连接
- 保持活动操作
- 保持活动和愚蠢代理
- 连接头和盲中继
- 代理和逐跳头部
代理连接黑客
HTTP/1.1 持久连接
管道连接
连接关闭的奥秘
- “随意” 断开连接
- 内容长度和截断
- 连接关闭容忍度、重试和幂等性
- 优雅的连接关闭
另见
- http://www.w3.org/Protocols/HTTP/Performance/
- http://www.acm.org/sigcomm/ccr/archive/2001/jan01/ccr-200101-mogul.pdf
第二部分. HTTP 架构#
第 05 章. Web 服务器#
Web 服务器实现: HTTP, TCP
通用软件 Web 服务器
Web 服务器设备
嵌入式 Web 服务器
真正的 Web 服务器的工作
* 第一步:接受客户端连接
* 处理新连接
* 客户端主机名识别(反向 DNS)
* 通过 ident 确定客户端用户
* 第二步:接收请求消息
* 消息的内部表示
* 连接输入 / 输出处理架构
* 第三步:处理请求
* 第四步:映射和访问资源
* 文档根(document root)
* 虚拟托管文档根
xml <VirtualHost www.marys-antiques.com> ServerName www.marys-antiques.com DocumentRoot /docs/mary TransferLog /logs/mary.access_log ErrorLog /logs/mary.error_log </VirtualHost>
* 用户主目录文档根(GET /~Bob/index.html
==> /home/Bob/index.html)
* 目录列表
* 动态内容资源映射
ScriptAlias /cgi-bin/ /usr/local/etc/httpd/cgi-programs/ AddHandler cgi-script .cgi
* 服务器端包含(SSI)
* 访问控制
* 第五步:构建响应
* 响应实体
* MIME 类型
* mime.types
* 魔法类型
* 显式类型(忽略文件扩展名或内容(可能是魔法数字))
* 类型协商
* 重定向
* 永久 / 临时移动的资源
* URL 增强
* 负载均衡
* 第六步:发送响应
* 第七步:日志记录
第 06 章。代理#
Web 中介
私有和共享代理
代理(中介)与网关(协议转换器)
为什么使用代理?
- 子女过滤器
- 文档访问控制器
- 安全防火墙
- Web 缓存
- 代理
- 内容路由器
- 转码器(
*.gif
==>*.jpeg
等) - 匿名化工具
代理去哪里?
代理服务器部署
* 出口代理(成人内容)
* 访问(入口)代理(ISP 访问代理:下载速度)
* 代理
* 网络交换代理
代理层次结构
- 入站
- 出站
- 父级
- 代理层次结构内容路由
代理如何获取流量
- 修改客户端(代理插件)
- 修改网络(拦截代理,如 GFW)
- 修改 DNS 命名空间
- 修改 Web 服务器
客户端代理设置
-
手动配置
-
浏览器预配置
-
代理自动配置:代理自动配置(PAC)
- 后缀: ".pac"
- MIME 类型: "application/x-ns-proxy-autoconfig"
-
客户端代理配置: Web 代理自动发现协议(WPAD)
- 动态主机发现协议(DHCP)
- 服务位置协议(SLP)
- DNS 知名主机名
- DNS SRV 记录
- DNS 服务 URI 在 TXT 记录中
-
代理请求的棘手问题
- 代理 URI 与服务器 URI 不同
- 服务器请求、显式代理请求、代理(反向代理)请求、拦截代理请求
-
虚拟托管的同样问题(index.html ==> bob/index.html? 或 tom/index.html?)
-
拦截代理获取部分 URI
-
代理可以处理代理和服务器请求
-
在途 URI 修改
- URI 客户端自动扩展和主机名解析
- 无代理的 URI 解析
- 使用显式代理的 URI 解析
- 使用拦截代理的 URI 解析
跟踪消息
- Via 头
- Via 语法
- Via 请求和响应路径
- Via 和网关
- 服务器和 Via 头
- Via 的隐私和安全影响
- TRACE 方法
- 最大转发
代理身份验证
代理互操作性
处理不支持的头部和方法
- OPTIONS: 发现可选功能支持
允许头
第 07 章。缓存#
冗余数据传输
带宽瓶颈
闪电人群
距离延迟
命中和未命中(命中,未命中,重新验证(新鲜度检查))
- 缓存命中
- 缓存未命中
- 重新验证命中(慢命中)
- 重新验证未命中
使用 If-Modified-Since 重新验证请求
- ==> 重新验证命中: 304(未修改)响应(“仍然新鲜”)
- ==> 重新验证未命中:正常 HTTP 200 OK 响应 + 完整内容,
命中率 / 比率(请求的分数)
字节命中率
区分命中和未命中
缓存拓扑
- 私有缓存(Firefox:
about:cache
) - 共享公共缓存(公共代理缓存)
代理缓存层次结构
缓存网格、内容路由和对等(兄弟缓存)
缓存处理步骤
- 第一步:接收
- 第二步:解析
- 第三步:查找
- 第四步:新鲜度检查
- 第五步:响应创建
- 第六步:发送
- 第七步:日志记录
缓存处理流程图
保持副本新鲜
- 文档过期
- Cache-Control: max-age=<max-age(以秒为单位)>
- Expires:
- 服务器重新验证
- 使用条件方法重新验证(条件请求)
- If-Modified-Since:
- If-None-Match: ETags(实体标签)
弱和强验证器
何时使用实体标签和最后修改日期
控制可缓存性
- No-Cache 和 No-Store 响应头
- Cache-Control: no-store
- Cache-Control: no-cache #(可能在本地缓存)
- Pragma: no-cache
- Max-Age 响应头
- Cache-Control: max-age=3600
- Cache-Control: s-maxage=3600 # 共享(公共)缓存
- Expires 响应头
- Expires:
- Must-Revalidate 响应头
- Cache-Control: must-revalidate
- 启发式过期
- LM-Factor 算法
- 客户端新鲜度约束
- Max-Age 响应头
- 客户端新鲜度约束
设置缓存控制
- 使用 Apache 控制 HTTP 头
- mod_headers(mod_headers 模块)
<Files *.html> Header set Cache-control no-cache </Files>
- mod_expires
- ExpiresDefault M86400
- ExpiresByType text/html "修改加 2 天 6 小时 12 分钟"
- mod_cern_meta
- mod_headers(mod_headers 模块)
- 通过 HTTP-EQUIV 控制 HTML 缓存
详细算法
- 年龄和新鲜度生命周期
- 年龄计算
- 明显年龄基于 Date 头
- 逐跳年龄计算
- 补偿网络延迟
- 新鲜度生命周期计算
...
缓存和广告
- 广告商的困境
- 发布者的回应(缓存破坏)
日志迁移
第 08 章。集成点:网关、隧道和中继#
客户端和服务器端网关
/
协议网关
- HTTP/*: 服务器端 Web 网关
- HTTP/HTTPS: 服务器端安全网关
- HTTPS/HTTP: 客户端安全加速网关
资源网关
- 通用网关接口(CGI)
- 服务器扩展 API
应用程序接口和 Web 服务
隧道
- 使用 CONNECT 建立 HTTP 隧道(原始字节中继)
- CONNECT 请求
CONNECT home.netscape.com:443 HTTP/1.0
User-agent: Mozilla/4.0 - CONNECT 响应
- 数据隧道、时序和连接管理
- SSL 隧道
- SSL 隧道与 HTTP/HTTPS 网关
- 隧道身份验证
- 隧道安全考虑
中继
第 09 章. Web 机器人#
爬虫和爬行
从哪里开始: “根集”
- 被困 — 孤立,
提取链接和规范化相对链接
- 循环和重复
面包屑的踪迹
- 树和哈希表
- 有损存在位图
- 检查点
- 分区
别名和机器人周期
- 规范化 URL
- 文件系统链接循环
- 动态虚拟 Web 空间
避免循环和重复
- 规范化 URL
- 广度优先爬行
- 限制
- 限制 URL 大小
- URL / 站点黑名单
- 模式检测(
/subdir/subdir/subdir...
) - 内容指纹识别
- 人工监控
机器人 HTTP
- 识别请求头
- 虚拟托管
- 条件请求
- 响应处理
- 状态码
- 实体
- 用户代理定位
行为不当的机器人
- 失控的机器人
- 过时的 URL
- 长且错误的 URL
- 好奇的机器人
- 动态网关访问
排除机器人
- 机器人排除标准(robots.txt)
- 网站和 robots.txt 文件
- 检索
robots.txt
并检查响应代码 - robots.txt 文件格式
User-Agent: <robot-name> # 机器人的名称的大小写不敏感子字符串
- 不允许 / 允许前缀匹配
- 其他 robots.txt 智慧
缓存和 robots.txt 的过期
机器人排除 Perl 代码
HTML 机器人控制 META 标签
NOINDEX, NOFOLLOW, INDEX, FOLLOW, NOARCHIVE, ALL, NONE
机器人礼仪
第 10 章. HTTP-NG#
HTTP 的成长痛
HTTP-NG活动 = HTTP: 下一代(HTTP-NG)
模块化和增强
- 层 {1..3}
- 分布式对象
- 第 1 层: 消息(WebMUX)
- 第 2 层:远程调用(二进制线协议)
- 第 3 层: Web 应用程序
第三部分。身份识别、授权和安全#
第 11 章。客户端识别和 Cookies#
个人化的触感
- HTTP 头
- 客户端 IP 地址
- 用户登录(不久,Fred 将放弃互联网,回去看 Oprah...)
- 冗长的 URL
- 丑陋的 URL
- 无法共享 URL
- 破坏缓存
- 额外的服务器负载
- 逃生舱口(可能会丢失购物车)
- 在会话之间不持久
- Cookies
- Cookies 的类型:会话和持久
- Cookies 的工作原理
- Cookie 罐:客户端状态
- 域
- allh
- 路径
- 安全
- 过期
- 名称
- 值
- 不同网站的不同 Cookies(
Set-Cookie: key=val
, Cookie: key=value)
- Cookie 域属性:
domain=<SITE>
,例如 "www.jianshu.com" - Cookie 路径属性:
path=/autos/
- Cookie 成分
- 版本 0(Netscape)Cookies
- 版本 1(RFC 2965)Cookies
- Cookies 和会话跟踪
- Cookies 和缓存
- 如果文档不可缓存,则标记文档
- 对缓存 Set-Cookie 头要谨慎
- 对带有 Cookie 头的请求要谨慎
- Cookies、安全性和隐私
第 12 章。基本身份验证#
- 身份验证
- 身份验证协议和头部
- 安全领域
- 基本身份验证
- 挑战 / 响应
- 挑战(server2client):
WWW-Authenticate: Basic realm=<quoted-realm>
- 响应(client2server):
Authorization: Basic <base64-username-and-password>
- Base-64 用户名 / 密码编码: BASE64ENC(:)
- 代理身份验证
Web 服务器 | 代理服务器 |
---|---|
未授权状态码: 401 | 未授权状态码: 407 |
WWW-Authenticate | Proxy-Authenticate |
授权 | Proxy-Authorization |
身份验证信息 | Proxy-Authentication-Info |
- 基本身份验证的安全缺陷
第 13 章。摘要身份验证#
摘要身份验证的改进
- 传输层安全(TLS)
- 安全 HTTP(HTTPS)
使用摘要保持密码秘密
单向摘要
-
摘要函数
的别名 =密码检查和
单向哈希函数或
指纹函数 ` -
MD5
输入 | MD5 摘要 |
---|---|
“Hi” | C1A5298F939E87E8F962A5EDFC206918 |
“bri!” | BEAAA0E34EBDB072F8627C038AB211F8 |
“3.1415926535897” | 475B977E19ECEE70835BC6DF46F4F6DE |
使用随机数防止重放
- 一个称为
nonce
的特殊令牌
摘要身份验证握手
- 挑战、随机数、算法...
摘要计算#
摘要算法输入数据
摘要是从三个组件计算得出的:
- 一对函数,由单向哈希函数 H (d) 和摘要 KD (s,d) 组成,其中 s 代表秘密,d 代表数据
- 一块包含安全信息的块,称为 A1,包括秘密密码
- 一块包含请求消息的非秘密属性的块,称为 A2
这两块数据,A1 和 A2,通过 H 和 KD 处理以产生摘要。
H() = MD5()
KD(,) = H(concatenate(:))
qop: 保护质量
: HTTP 请求方法
: 请求行中的请求 URI
nc: 随机数计数
与安全相关的数据(A1)
算法 | A1 |
---|---|
MD5 | A1 = :: |
MD5-sess | A1 = MD5(::):: |
与消息相关的数据(A2)
qop | A2 |
---|---|
未定义 | : |
auth | : |
auth-int | :() |
总体摘要算法
- 旧的和新的摘要算法
| qop | 摘要算法 | 备注 |
| :---: | :---: | :---: |
| 未定义 | KD (H (A1), (A2)) | 已弃用 |
| auth 或 auth-int | KD (H (A1), :::(A2)) | 优选 | - 展开的摘要算法备忘单
| qop | 算法 | 展开的算法 |
| :---: | :---: | :---: |
| 未定义 | <未定义>, MD5, MD5-sess | MD5 (MD5 (A1):(A2)) |
| auth | <未定义>, MD5, MD5-sess | MD5 (MD5 (A1)::::(A2)) |
| auth-int | <未定义>, MD5, MD5-sess | MD5 (MD5 (A1)::::(A2)) |
摘要身份验证会话
预先授权
- 下一个随机数预生成
- 限制随机数重用
- 同步随机数生成
随机数选择
- RFC 2617 建议,随机数 = BASE64(时间戳 H(时间戳:“ETag:“私钥”))
- ETag: 与请求实体关联的 HTTP ETag 头
对称身份验证
- 按算法定义 A2(请求摘要)
| qop | A2 |
| :---: | :---: |
| 未定义 | : |
| auth | : |
| auth-int | :() | - 按算法定义 A2(响应摘要)
| qop | A2 |
| :---: | :---: |
| 未定义 | : |
| auth | : |
| auth-int | :() |
保护质量增强
- 使用 qop 是可选的,但仅用于与旧的 RFC 2069 规范向后兼容。
消息完整性保护
摘要身份验证头
实际考虑
- 多次挑战
- 错误处理
- 保护空间
- 重写 URI
- 缓存
安全考虑
- 头部篡改
- 重放攻击
- 多种身份验证机制
- 字典攻击
- 敌对代理和中间人攻击
- 选择明文攻击
- 存储密码
第 14 章。安全 HTTP#
使 HTTP 安全
HTTPS
数字密码学:秘密编码的艺术与科学
密码
对称密钥密码学
- (e=k),编码 = 解码
- P = D(C, d)
- DES、Triple-DES、RC2 和 RC4
- 密钥长度和枚举攻击