标签 http 下的文章

自从我写了上一篇博文之后,就再也找不到空闲时间写文章了。今天我终于可以抽出时间写一些关于 HTTP 的东西。

我认为每一个 web 开发者都应该对这个支撑了整个 Web 世界的 HTTP 协议有所了解,这样才能帮助你更好的完成开发任务。

在这篇文章中,我将讨论什么是 HTTP,它是怎么产生的,它的地位,以及我们应该怎么使用它。

HTTP 是什么

首先我们要明白 HTTP 是什么。HTTP 是一个基于 TCP/IP 的应用层通信协议,它是客户端和服务端在互联网互相通讯的标准。它定义了内容是如何通过互联网进行请求和传输的。HTTP 是在应用层中抽象出的一个标准,使得主机(客户端和服务端)之间的通信得以通过 TCP/IP 来进行请求和响应。TCP 默认使用的端口是 80,当然也可以使用其它端口,比如 HTTPS 使用的就是 443 端口。

HTTP/0.9 - 单行协议 (1991)

HTTP 最早的规范可以追溯到 1991 年,那时候的版本是 HTTP/0.9,该版本极其简单,只有一个叫做 GET的请求方式。如果客户端要访问服务端上的一个页面,只需要如下非常简单的请求:

GET /index.html

服务端对应的返回类似如下:

(response body)
(connection closed)

就这么简单,服务端捕获到请求后立马返回 HTML 并且关闭连接,在这之中

  • 没有 头信息 headers
  • 仅支持 GET 这一种请求方法
  • 必须返回 HTML

如同你所看到的,当时的 HTTP 协议只是一块基础的垫脚石。

HTTP/1.0 - 1996

在 1996 年,新版本的 HTTP 对比之前的版本有了极大的改进,同时也被命名为 HTTP/1.0

HTTP/0.9 只能返回 HTML 不同的是,HTTP/1.0 支持处理多种返回的格式,比如图片、视频、文本或者其他格式的文件。它还增加了更多的请求方法(如 POSTHEAD),请求和响应的格式也相应做了改变,两者都增加了头信息;引入了状态码来定义返回的特征;引入了字符集支持;支持 多段类型 multi-part 、用户验证信息、缓存、内容编码格式等等。

一个简单的 HTTP/1.0 请求大概是这样的:

GET / HTTP/1.0
Host: kamranahmed.info
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*

正如你所看到的,在请求中附带了客户端中的一些个人信息、响应类型要求等内容。这些是在 HTTP/0.9 无法实现的,因为那时候没有头信息。

一个对上述请求的响应例子如下所示:

HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84

(response body)
(connection closed)

HTTP/1.0 (HTTP 后面跟的是版本号)早期开始,在状态码 200 之后就附带一个原因短语(你可以用来描述状态码)。

在这个较新一点的版本中,请求和响应的头信息仍然必须是 ASCII 编码,但是响应的内容可以是任意类型,如图片、视频、HTML、文本或其他类型,服务器可以返回任意内容给客户端。所以这之后,HTTP 中的“ 超文本 Hyper Text ”成了名不副实。 HMTP 超媒体传输协议 Hypermedia transfer protocol )可能会更有意义,但是我猜我们还是会一直沿用这个名字。

HTTP/1.0 的一个主要缺点就是它不能在一个连接内拥有多个请求。这意味着,当客户端需要从服务器获取东西时,必须建立一个新的 TCP 连接,并且处理完单个请求后连接即被关闭。需要下一个东西时,你必须重新建立一个新的连接。这样的坏处在哪呢?假设你要访问一个有 10 张图片,5 样式表 stylesheet 5 个 JavaScript 的总计 20 个文件才能完整展示的一个页面。由于一个连接在处理完成一次请求后即被关闭,所以将有 20 个单独的连接,每一个文件都将通过各自对应的连接单独处理。当连接数量变得庞大的时候就会面临严重的性能问题,因为 TCP 启动需要经过三次握手,才能缓慢开始。

三次握手

三次握手是一个简单的模型,所有的 TCP 连接在传输应用数据之前都需要在三次握手中传输一系列数据包。

  • SYN - 客户端选取一个随机数,我们称为 x,然后发送给服务器。
  • SYN ACK - 服务器响应对应请求的 ACK 包中,包含了一个由服务器随机产生的数字,我们称为 y,并且把客户端发送的 x+1,一并返回给客户端。
  • ACK - 客户端在从服务器接受到 y 之后把 y 加上 1 作为一个 ACK 包返回给服务器。

一旦三次握手完成后,客户端和服务器之间就可以开始交换数据。值得注意的是,当客户端发出最后一个 ACK 数据包后,就可以立刻向服务器发送应用数据包,而服务器则需要等到收到这个 ACK 数据包后才能接受应用数据包。

请注意,上图有点小问题,客户端发回的最后一个 ACK 包仅包含 y+1,上图应该是 ACK:y+1 而不是 ACK:x+1,y+1

然而,某些 HTTP/1.0 的实现试图通过新引入一个称为 Connection: keep-alive 的头信息来克服这一问题,这个头信息意味着告诉服务器“嘿,服务器,请不要关闭此连接,我还要用它”。但是,这并没有得到广泛的支持,问题依然存在。

除了无连接之外,HTTP 还是一个无状态的协议,即服务器不维护有关客户端的信息。因此每个请求必须给服务器必要的信息才能完成请求,每个请求都与之前的旧的请求无关。所以,这增加了推波助澜的作用,客户端除了需要新建大量连接之外,在每次连接中还需要发送许多重复的数据,这导致了带宽的大量浪费。

HTTP/1.1 - 1999

HTTP/1.0 经过仅仅 3 年,下一个版本,即 HTTP/1.1 就在 1999 年发布了,改进了它的前身很多问题,主要的改进包括:

  • 增加了许多 HTTP 请求方法,包括 PUTPATCHHEADOPTIONSDELETE
  • 主机标识符 HostHTTP/1.0 并不是必须的,而在 HTTP/1.1 是必须的。
  • 如上所述的持久连接。在 HTTP/1.0 中每个连接只有一个请求并在该请求结束后被立即关闭,这导致了性能问题和增加了延迟。 HTTP/1.1 引入了持久连接,即连接在默认情况下是不关闭并保持开放的,这允许多个连续的请求使用这个连接。要关闭该连接只需要在头信息加入 Connection: close,客户通常在最后一个请求里发送这个头信息就能安全地关闭连接。
  • 新版本还引入了“ 管线化 pipelining ”的支持,客户端可以不用等待服务器返回响应,就能在同一个连接内发送多个请求给服务器,而服务器必须以接收到的请求相同的序列发送响应。但是你可能会问了,客户端如何知道哪里是第一个响应下载完成而下一个响应内容开始的地方呢?要解决这个问题,头信息必须有 Content-Length,客户可以使用它来确定哪些响应结束之后可以开始等待下一个响应。

    • 值得注意的是,为了从持久连接或管线化中受益, 头部信息必须包含 Content-Length,因为这会使客户端知道什么时候完成了传输,然后它可以发送下一个请求(持久连接中,以正常的依次顺序发送请求)或开始等待下一个响应(启用管线化时)。
    • 但是,使用这种方法仍然有一个问题。那就是,如果数据是动态的,服务器无法提前知道内容长度呢?那么在这种情况下,你就不能使用这种方法中获益了吗?为了解决这个问题,HTTP/1.1 引进了分块编码。在这种情况下,服务器可能会忽略 Content-Length 来支持分块编码(更常见一些)。但是,如果它们都不可用,那么连接必须在请求结束时关闭。
  • 在动态内容的情况下分块传输,当服务器在传输开始但无法得到 Content-Length 时,它可能会开始按块发送内容(一块接一块),并在传输时为每一个小块添加 Content-Length。当发送完所有的数据块后,即整个传输已经完成后,它发送一个空的小块,比如设置 Content-Length 为 0 ,以便客户端知道传输已完成。为了通知客户端块传输的信息,服务器在头信息中包含了 Transfer-Encoding: chunked
  • 不像 HTTP/1.0 中只有 Basic 身份验证方式,HTTP/1.1 包括 摘要验证方式 digest authentication 代理验证方式 proxy authentication
  • 缓存。
  • 范围请求 Byte Ranges
  • 字符集。
  • 内容协商 Content Negotiation
  • 客户端 cookies。
  • 支持压缩。
  • 新的状态码。
  • 等等。

我不打算在这里讨论所有 HTTP/1.1 的特性,因为你可以围绕这个话题找到很多关于这些的讨论。我建议你阅读 HTTP/1.0HTTP/1.1 版本之间的主要差异,希望了解更多可以读原始的 RFC

HTTP/1.1 在 1999 年推出,到现在已经是多年前的标准。虽然,它比前一代改善了很多,但是网络日新月异,它已经垂垂老矣。相比之前,加载网页更是一个资源密集型任务,打开一个简单的网页已经需要建立超过 30 个连接。你或许会说,HTTP/1.1 具有持久连接,为什么还有这么多连接呢?其原因是,在任何时刻 HTTP/1.1 只能有一个未完成的连接。 HTTP/1.1 试图通过引入管线来解决这个问题,但它并没有完全地解决。因为一旦管线遇到了缓慢的请求或庞大的请求,后面的请求便被阻塞住,它们必须等待上一个请求完成。为了克服 HTTP/1.1 的这些缺点,开发人员开始实现一些解决方法,例如使用 spritesheets、在 CSS 中编码图像、单个巨型 CSS / JavaScript 文件、域名切分等。

SPDY - 2009

谷歌走在业界前列,为了使网络速度更快,提高网络安全,同时减少网页的等待时间,他们开始实验替代的协议。在 2009 年,他们宣布了 SPDY

SPDY 是谷歌的商标,而不是一个缩写。

显而易见的是,如果我们继续增加带宽,网络性能开始的时候能够得到提升,但是到了某个阶段后带来的性能提升就很有限了。但是如果把这些优化放在等待时间上,比如减少等待时间,将会有持续的性能提升。这就是 SPDY 优化之前的协议的核心思想,减少等待时间来提升网络性能。

对于那些不知道其中区别的人,等待时间就是延迟,即数据从源到达目的地需要多长时间(单位为毫秒),而带宽是每秒钟数据的传输量(比特每秒)。

SPDY 的特点包括:复用、压缩、优先级、安全性等。我不打算展开 SPDY 的细节。在下一章节,当我们将介绍 HTTP/2,这些都会被提到,因为 HTTP/2 大多特性是从 SPDY 受启发的。

SPDY 没有试图取代 HTTP,它是处于应用层的 HTTP 之上的一个传输层,它只是在请求被发送之前做了一些修改。它开始成为事实标准,大多数浏览器都开始支持了。

2015年,谷歌不想有两个相互竞争的标准,所以他们决定将其合并到 HTTP 协议,这样就导致了 HTTP/2 的出现和 SPDY 的废弃。

HTTP/2 - 2015

现在想必你明白了为什么我们需要另一个版本的 HTTP 协议了。 HTTP/2 是专为了低延迟地内容传输而设计。主要特点和与 HTTP/1.1 的差异包括:

  • 使用二进制替代明文
  • 多路传输 - 多个异步 HTTP 请求可以使用单一连接
  • 报头使用 HPACK 压缩
  • 服务器推送 - 单个请求多个响应
  • 请求优先级
  • 安全性

1. 二进制协议

HTTP/2 通过使其成为一个二进制协议以解决 HTTP/1.x 中存在的延迟问题。作为一个二进制协议,它更容易解析,但可读性却不如 HTTP/1.x frames stream 的概念组成了 HTTP/2 的主要部分。

帧和流

现在 HTTP 消息是由一个或多个帧组成的。HEADERS 帧承载了 元数据 meta data DATA 帧则承载了内容。还有其他类型的帧(HEADERSDATARST_STREAMSETTINGSPRIORITY 等等),这些你可以通过 HTTP/2 规范来了解。

每个 HTTP/2 请求和响应都被赋予一个唯一的流 ID,并切分成帧。帧就是一小片二进制数据。帧的集合称为流,每个帧都有个标识了其所属流的流 ID,所以在同一个流下的每个帧具有共同的报头。值得注意的是,​除了流 ID 是唯一的之外,​由客户端发起的请求使用了奇数作为流 ID,从来自服务器的响应使用了偶数作为流 ID。

除了 HEADERS 帧和 DATA 帧,另一个值得一提的帧是 RST_STREAM。这是一个特殊的帧类型,用来中止流,即客户可以发送此帧让服务器知道,我不再需要这个流了。在 HTTP/1.1 中让服务器停止给客户端发送响应的唯一方法是关闭连接,这样造成了延迟增加,因为之后要发送请求时,就要必须打开一个新的请求。而在 HTTP/2,客户端可以使用 RST_STREAM 来停止接收特定的数据流,而连接仍然打开着,可以被其他请求使用。

2. 多路传输

因为 HTTP/2 是一个二进制协议,而且如上所述它使用帧和流来传输请求与响应,一旦建立了 TCP 连接,相同连接内的所有流都可以同过这个 TCP 连接异步发送,而不用另外打开连接。反过来说,服务器也可以使用同样的异步方式返回响应,也就是说这些响应可以是无序的,客户端使用分配的流 ID 来识别数据包所属的流。这也解决了 HTTP/1.x 中请求管道被阻塞的问题,即客户端不必等待占用时间的请求而其他请求仍然可以被处理。

3. HPACK 请求头部压缩

RFC 花了一篇文档的篇幅来介绍针对发送的头信息的优化,它的本质是当我们在同一客户端上不断地访问服务器时,许多冗余数据在头部中被反复发送,有时候仅仅是 cookies 就能增加头信息的大小,这会占用许多宽带和增加传输延迟。为了解决这个问题,HTTP/2 引入了头信息压缩。

不像请求和响应那样,头信息中的信息不会以 gzip 或者 compress 等格式压缩。而是采用一种不同的机制来压缩头信息,客户端和服务器同时维护一张头信息表,储存了使用了哈夫曼编码进行编码后的头信息的值,并且后续请求中若出现同样的字段则忽略重复值(例如 用户代理 user agent 等),只发送存在两边信息表中它的引用即可。

我们说的头信息,它们同 HTTP/1.1 中一样,并在此基础上增加了一些伪头信息,如 :scheme:host:path

4. 服务器推送

服务器推送是 HTTP/2 的另一个巨大的特点。对于服务器来说,当它知道客户端需要一定的资源后,它可以把数据推送到客户端,即使客户端没有请求它。例如,假设一个浏览器在加载一个网页时,它解析了整个页面,发现有一些内容必须要从服务端获取,然后发送相应的请求到服务器以获取这些内容。

服务器推送减少了传输这些数据需要来回请求的次数。它是如何做到的呢?服务器通过发送一个名字为 PUSH_PROMISE 特殊的帧通知到客户端“嘿,我准备要发送这个资源给你了,不要再问我要了。”这个 PUSH_PROMISE 帧与要产生推送的流联系在一起,并包含了要推送的流 ID,也就是说这个流将会被服务器推送到客户端上。

5. 请求优先级

当流被打开的时候,客户端可以在 HEADERS 帧中包含优先级信息来为流指定优先级。在任何时候,客户端都可以发送 PRIORITY 帧来改变流的优先级。

如果没有任何优先级信息,服务器将异步地无序地处理这些请求。如果流分配了优先级,服务器将基于这个优先级来决定需要分配多少资源来处理这个请求。

6. 安全性

在是否强制使用 TLS 来增加安全性的问题上产生了大范围的讨论,讨论的结果是不强制使用。然而大多数厂商只有在使用 TLS 时才能使用 HTTP/2。所以 HTTP/2 虽然规范上不要求加密,但是加密已经约定俗成了。这样,在 TLS 之上实现 HTTP/2 就有了一些强制要求,比如,TLS 的最低版本为 1.2,必须达到某种级别的最低限度的密钥大小,需要布署 ephemeral 密钥等等。

到现在 HTTP/2 已经完全超越了 SPDY,并且还在不断成长,HTTP/2 有很多关系性能的提升,我们应该开始布署它了。

如果你想更深入的了解细节,请访问该规范的链接HTTP/2 性能提升演示的链接。请在留言板写下你的疑问或者评论,最后如果你发现有错误,请同样留言指出。

这就是全部了,我们之后再见~


via: http://kamranahmed.info/blog/2016/08/13/http-in-depth/

作者:Kamran Ahmed 译者:NearTan 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这是一个针对 PHP、Go、Python 等语言的 CGI 应用的漏洞。

httpoxy 是一系列影响到以 CGI 或类 CGI 方式运行的应用的漏洞名称。简单的来说,它就是一个名字空间的冲突问题。

  • RFC 3875 (CGI)中定义了从 HTTP 请求的 Proxy 头部直接填充到环境变量 HTTP_PROXY 的方式
  • HTTP_PROXY 是一个常用于配置外发代理的环境变量

这个缺陷会导致远程攻击。如果你正在运行着 PHP 或 CGI 程序,你应该马上封挡 Proxy 头部!马上! 具体做法参见下面。httpoxy 是一个服务器端 web 应用漏洞,如果你没有在服务器端部署这些代码,则不用担心。

如果我的 Web 应用存在这种漏洞会怎么样?

当一个利用了此漏洞的 HTTP 客户端发起请求时,它可以做到:

  • 通过你的 Web 应用去代理请求别的 URL
  • 直接让你的服务器打开指定的远程地址及端口
  • 浪费服务器的资源,替攻击者访问指定的资源

httpoxy 漏洞非常容易利用。希望安全人员尽快扫描该漏洞并快速修复。

哪些受到影响?

以下情况会存在安全漏洞:

  • 代码运行在 CGI 上下文中,这样 HTTP_PROXY 就会变成一个真实的或模拟的环境变量
  • 一个信任 HTTP_PROXY的 HTTP 客户端,并且支持代理功能
  • 该客户端会在请求内部发起一个 HTTP(或 HTTPS)请求

下列情形是已经发现存在该缺陷的环境:

语言环境HTTP 客户端
PHPphp-fpm mod\_phpGuzzle 4+ Artax
Pythonwsgiref.handlers.CGIHandler twisted.web.twcgi.CGIScriptrequests
Gonet/http/cginet/http

肯定还有很多我们没有确定是否存在缺陷的语言和环境。

PHP

  • 是否存在缺陷依赖于你的应用代码和 PHP 库,但是影响面看起来似乎非常广泛
  • 只要在处理用户请求的过程中使用了一个带有该缺陷的库,就可能被利用
  • 如果你使用了有该缺陷的库,该缺陷会影响任意 PHP 版本

    • 甚至会影响到替代的 PHP 运行环境,比如部署在 FastCGI 模式下的 HHVM
  • 确认影响 Guzzle、Artax 等库,可能还有很多很多的库也受影响

    • Guzzle 4.0.0rc2 及其以后版本受影响,Guzzle 3 及更低版本不受影响
    • 其它的例子还有 Composer 的 StreamContextBuilder 工具类

举个例子说,如果你在 Drupal 中使用 Guzzle 6 模块发起外发请求(比如请求一个天气 API),该模块发起的请求就存在这个 httpoxy 缺陷。

Python

  • Python 代码只有部署在 CGI 模式下才存在缺陷,一般来说,存在缺陷的代码会使用类似 wsgiref.handlers.CGIHandler 的 CGI 控制器

    • 正常方式部署的 Python web 应用不受影响(大多数人使用 WSGI 或 FastCGI,这两个不受影响),所以受到影响的 Python 应用要比 PHP 少得多
    • wsgi 不受影响,因为 os.environ 不会受到 CGI 数据污染
  • 存在缺陷的 requests 库必须信任和使用 os.environ['HTTP_PROXY'],并且不做内容检查

Go

  • Go 代码必须部署在 CGI 下才受影响。一般来说受到影响的代码会使用 net/http/cgi

    • 像 Python 一样,这并不是部署 Go 为一个 Web 应用的通常方式。所以受到影响的情形很少
    • 相较而言,Go 的 net/http/fcgi 包并不设置实际的环境变量,所以不受影响
  • 存在缺陷的 net/http 版本需要在外发请求中信任并使用 HTTP_PROXY ,并不做内容检查

马上修复

最好的修复方式是在他们攻击你的应用之前尽早封挡 Proxy 请求头部。这很简单,也很安全。

  • 说它安全是因为 IETF 没有定义 Proxy 请求头部,也没有列在 IANA 的消息头部注册中。这表明对该头部的使用是非标准的,甚至也不会临时用到
  • 符合标准的 HTTP 客户端和服务器绝不应该读取和发送这个头部
  • 你可以从请求中去掉这个头部或者干脆整个封挡使用它的请求
  • 你可以在上游没有发布补丁时自己来解决这个问题

    • 当 HTTP 请求进来时就检查它,这样可以一次性修复好许多存在缺陷的应用
    • 在反向代理和应用防火墙之后的应用剔除 Proxy 请求头部是安全的

如何封挡 Proxy 请求头部依赖于你的配置。最容易的办法是在你的 Web 应用防火墙上封挡该头部,或者直接在 Apache 和 Nginx 上做也行。以下是一些如何做的指导:

Nginx/FastCGI

使用如下语句封挡传递给 PHP-FPM、PHP-PM 的请求头,这个语句可以放在 fastcgi.conf 或 fastcgi\_param 中(视你使用了哪个配置文件):

fastcgi_param HTTP_PROXY "";

在 FastCGI 模式下,PHP 存在缺陷(但是大多数使用 Nginx FastCGI 的其它语言则不受影响)。

Apache

对于 Apache 受影响的具体程度,以及其它的 Apache 软件项目,比如 Tomcat ,推荐参考 Apache 软件基金会的官方公告。 以下是一些主要信息:

如果你在 Apache HTTP 服务器中使用 mod_cgi来运行 Go 或 Python 写的脚本,那么它们会受到影响(这里 HTTP_PROXY 环境变量是“真实的”)。而 mod_php 由于用于 PHP 脚本,也存在该缺陷。

如果你使用 mod\_headers 模块,你可以通过下述配置在进一步处理请求前就 unset 掉 Proxy 请求头部:

RequestHeader unset Proxy early

如果你使用 mod\_security 模块,你可以使用一个 SecRule 规则来拒绝带有 Proxy 请求头部的请求。下面是一个例子,要确保 SecRuleEngine 打开了。你可以根据自己的情况调整。

SecRule &REQUEST_HEADERS:Proxy "@gt 0" "id:1000005,log,deny,msg:'httpoxy denied'"

最后,如果你使用 Apache Traffic Server 的话,它本身不受影响。不过你可以用它来剔除掉 Proxy 请求头部,以保护其后面的其它服务。具体可以参考 ASF 指导

HAProxy

通过下述配置剔除该请求头部:

http-request del-header Proxy

Varnish

通过下述语句取消该头部,请将它放到已有的 vcl\_recv 小节里面:

sub vcl_recv {
    [...]
    unset req.http.proxy;
    [...]
}

OpenBSD relayd

使用如下语句移除该头部。把它放到已有的过滤器里面:

http protocol httpfilter {
    match request header remove "Proxy"
}

lighttpd (<= 1.4.40)

弹回包含 Proxy 头部的请求。

  • 创建一个 /path/to/deny-proxy.lua文件,让它对于 lighttpd 只读,内容如下:
if (lighty.request["Proxy"] == nil) then return 0 else return 403 end
  • 修改 lighttpd.conf 以加载 mod_magnet 模块,并运行如上 lua 代码:
server.modules += ( "mod_magnet" )
magnet.attract-raw-url-to = ( "/path/to/deny-proxy.lua" )

lighttpd2 (开发中)

从请求中剔除 Proxy 头部。加入如下语句到 lighttpd.conf中:

req_header.remove "Proxy";

用户端的 PHP 修复没有作用

用户端的修复不能解决该缺陷,所以不必费劲:

  • 使用 unset($_SERVER['HTTP_PROXY']) 并不会影响到 getenv() 返回的值,所以无用
  • 使用 putenv('HTTP_PROXY=') 也没效果(putenv 只能影响到来自实际环境变量的值,而不是来自请求头部的)

httpoxy 的历史

该漏洞首次发现与15年前。

2001 年 3 月
Randal L. Schwartz 在 libwww-perl 发现该缺陷并修复。

2001 年 4 月
Cris Bailiff 在 curl 中发现该缺陷并修复。

2012 年 7 月
Net::HTTPHTTP_PROXY 实现中, Ruby 团队的 Akira Tanaka 发现了该缺陷

2013 年 11 月
在 nginx 邮件列表中提到了该缺陷。发现者 Jonathan Matthews 对此不太有把握,不过事实证明他是对的。

2015 年 2 月
Stefan Fritsch 在 Apache httpd-dev 邮件列表中提到了它。

2016 年 7 月
Vend 安全团队的 Scott Geary 发现了对该缺陷,并且它影响到了 PHP 等许多现代的编程语言和库。

所以,这个缺陷已经潜伏了许多年,许多人都在不同方面发现了它的存在,但是没有考虑到它对其它语言和库的影响。安全研究人员为此专门建立了一个网站: https://httpoxy.org/ ,可以在此发现更多内容。

上周五,IESG( 互联网工程指导委员会 Internet Engineering Steering Group )批准了一个新的互联网标准,为 HTTP 增加了一个新状态码:451 Unavailable For Legal Reasons。还需要一点点工作就会发布为正式的 RFC ,不过现在已经可以用了。

缘起

几年前,英国政府要求 ISP 们对海盗湾的内容进行封挡,Terence Eden 就这个事情写了一个帖子,建议应该有一个不同的状态码来区分禁止访问的原因。这样的话,ISP 们就可以向他们的用户说明为什么这些资源不能访问。有人提议使用数字 451 作为状态码,也有各种其它的建议。

谷歌的 Tim Bray 受此启发,于前几年 HTTP 工作组 HTTP Working Group 提交了一份提案,他(及很多人)认为应该将由于技术原因的不可见与非技术原因的不可见区分开来:

  • 403 状态码,用于描述由于技术原因禁止访问
  • 451 状态码,则用于描述由于国家法律所要求而禁止访问

据说,451 这个数字来源于 Ray Bradbury 的一篇小说《 华氏 451 Fahrenheit 451 》。

发展

最初,对于这份提案,IETF HTTP 工作组的主席 Mark Nottingham 是拒绝的。因为 HTTP 状态码是有限的,虽然说从 400 到 499 有足足一百个位置,但是谁也不知道将来会有什么需求。而当时也没有任何需要让程序/机器来区分禁止访问的这两种情形,所以不应该浪费代码——最多,在 HTTP 首部或页面上呈现具体原因就可以了。

而 Tim 依旧坚持他的提案,并偶尔更新一下提案内容,和关心这件事的人谈论。

有一些站点开始实验性的使用这个状态码,不过这并不足以让 IESG 同意增加新的状态码。但是,随着网络上的审查的越来越多,比如欧盟政府要求 ISP 禁止对盗版内容的访问,而韩国、俄罗斯和其它一些国家会限制某些内容的访问等等,IESG 意识到网站需要能够区分这其中的不同。

此外,还有一些人希望能够自动找到和分类哪些内容是被审查的。这就需要一种机器可读的机制来区分 403 和 451 所代表的不同意义。

451 能做什么和不能做什么

虽然 451 状态码的原意是用于标示出哪些内容是被法律禁止访问的,比如可以用在网络设备上(比如防火墙)或 Web 服务器上。就目前已知的, GithubTwitterFacebookGoogle 都已经开始使用这个状态码来应对各个国家地区的审查要求了。

但是显然,451 状态码并不能标示出所有的被审查的内容,也许有些国家(比如英国)的法律要求不允许使用这个状态码。

本文内容编译自 Mark Nottingham 的博客、维基百科、Solidot 等来源。

假设由于某种原因,你需要嗅探HTTP站点的流量(如HTTP请求与响应)。举个例子,你可能在测试一个web服务器的实验性功能,或者你在为某个web应用或RESTful服务排错,又或者你正在为PAC(proxy auto config)排错或寻找某个站点下载的恶意软件。不论什么原因,在这些情况下,进行HTTP流量嗅探对于系统管理、开发者、甚至最终用户来说都是很有帮助的。

数据包嗅工具tcpdump被广泛用于实时数据包的导出,但是你需要设置过滤规则来捕获HTTP流量,甚至它的原始输出通常不能方便的停在HTTP协议层。实时web服务器日志解析器如ngxtop可以提供可读的实时web流量跟踪痕迹,但这仅适用于可完全访问live web服务器日志的情况。

要是有一个仅用于抓取HTTP流量的类似tcpdump的数据包嗅探工具就非常好了。事实上,httpry就是:HTTP包嗅探工具。httpry捕获HTTP数据包,并且将HTTP协议层的数据内容以可读形式列举出来。通过这篇指文章,让我们了解如何使用httpry工具嗅探HTTP流量。

在Linux上安装httpry

基于Debian系统(Ubuntu 或 LinuxMint),基础仓库中没有httpry安装包(译者注:本人ubuntu14.04,仓库中已有包,可直接安装)。所以我们需要通过源码安装:

$ sudo apt-get install gcc make git libpcap0.8-dev
$ git clone https://github.com/jbittel/httpry.git
$ cd httpry
$ make
$ sudo make install

在Fedora,CentOS 或 RHEL系统,可以使用如下yum命令安装httpry。在CentOS/RHEL系统上,运行yum之前使其能够访问EPEL repo

$ sudo yum install httpry 

如果你仍想通过基于RPM系统的源码来安装httpry的话,你可以通过这几个步骤实现:

$ sudo yum install gcc make git libpcap-devel
$ git clone https://github.com/jbittel/httpry.git
$ cd httpry
$ make
$ sudo make install 

httpry的基本用法

以下是httpry的基本用法

$ sudo httpry -i <network-interface> 

httpry就会监听指定的网络接口,并且实时的显示捕获到的HTTP请求/相应。

在大多数情况下,由于发送与接到的数据包过多导致刷屏很快,难以分析。这时候你肯定想将捕获到的数据包保存下来以便离线分析。可以使用'b'或'-o'选项保存数据包。'-b'选项将数据包以二进制文件的形式保存下来,这样可以使用httpry软件打开文件以浏览。另一方面,'-o'选项将数据以可读的字符文件形式保存下来。

以二进制形式保存文件:

$ sudo httpry -i eth0 -b output.dump

浏览所保存的HTTP数据包文件:

$ httpry -r output.dump

注意,不需要根用户权限就可以使用'-r'选项读取数据文件。

将httpry数据以字符文件保存:

$ sudo httpry -i eth0 -o output.txt

httpry 的高级应用

如果你想监视指定的HTTP方法(如:GET,POST,PUT,HEAD,CONNECT等),使用'-m'选项:

$ sudo httpry -i eth0 -m get,head

如果你下载了httpry的源码,你会发现源码下有一些Perl脚本,这些脚本用于分析httpry输出。脚本位于目录httpry/scripts/plugins。如果你想写一个定制的httpry输出分析器,则这些脚可以作为很好的例子。其中一些有如下的功能:

  • hostnames: 显示唯一主机名列表。
  • find\_proxies: 探测web代理。
  • search\_terms: 查找及统计在搜索服务里面的搜索词。
  • content\_analysis: 查找含有指定关键的URL。
  • xml\_output: 将输出转换为XML形式。
  • log\_summary: 生成日志汇总。
  • db\_dump: 将日志文件数据保存数据库。

在使用这些脚本之前,首先使用'-o'选项运行httpry。当获取到输出文件后,立即使用如下命令执行脚本:

$ cd httpry/scripts
$ perl parse_log.pl -d ./plugins <httpry-output-file>

你可能在使用插件的时候遇到警告。比如,如果你没有安装带有DBI接口的MySQL数据库,那么使用db\_dump插件时可能会失败。如果一个插件初始化失败的话,那么只是这个插件不能使用,所以你可以忽略那些警告。

当parse\_log.pl完成后,你将在httpry/scripts 目录下看到数个分析结果。例如,log\_summary.txt 与如下内容类似。

总的来说,当你要分析HTTP数据包的时候,httpry非常有用。它可能并不被大多Linux使用者所熟知,但会用总是有好处的。你觉得这个工具怎么样呢?


via: http://xmodulo.com/2014/08/sniff-http-traffic-command-line-linux.html

作者:Dan Nanni 译者:DoubleC 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

对 Ubuntu 默认的 Ambiance 主题不太满意?何不试试其它的主题,用换主题的方式来改变你的桌面外观?如果你不知道哪些主题对你有用的话,我已经列出了 Ubuntu 13.10 最好的主题。在我们看这些主题前,用简单的句子说明下该怎么样使用这些主题。

在 Ubuntu 13.10 中安装主题

在 Ubuntu 中要使用主题有两种方式,既可以添加 PPA 来下载也可以直接下载主题文件。如果你是直接下载的文件,要把它解压到 ~/.themes 或者 /user/share/themes 目录中。如果你是通过添加 PPA 来下载的,并不需要做什么特殊的操作。

下一步就是正式使用已经安装的主题。你可以使用 Unity Tweak 工具软件来切换到已经安装的主题。请参考这篇文章如何在 Ubuntu 13.10 上安装主题上的截图教程.

Ubuntu 13.10 最好的 Unity 主题:

大多数主题都是由主题本身和图标集组成的。我的建议是主题本身及图标集都要从同一个主题集中安装,以使它们更漂亮。事不宜迟,让我们看些 Ubuntu13.10 中最好的主题:

Numix

Numix 确实是一款漂亮的主题。它有着扁平和弧形图标,并且完美的集成进 Unity 桌面环境中。在终端下可以使用下面的命令来安装 Numix 主题和图表集:

sudo add-apt-repository ppa:numix/ppa
sudo apt-get update
sudo apt-get install numix-gtk-theme numix-icon-theme numix-icon-theme-circle numix-wallpaper-saucy

Moka

漂亮,不是吗?使用如下命令来安装 Moka GTK 主题和图标集:

sudo add-apt-repository ppa:snwh/moka-gtk-theme-daily
sudo add-apt-repository ppa:snwh/moka-icon-theme-daily
sudo apt-get update
sudo apt-get install moka-gtk-theme moka-icon-theme moka-icon-theme-symbolic moka-icon-theme-extras

zonColor

zonColor 是从亮到暗及颜色相异的几个主题组成的一个包。它也由自己的图标集。使用如下的命令来安装 zonColor 主题和图标集。

sudo add-apt-repository ppa:noobslab/themes
sudo add-apt-repository ppa:noobslab/icons
sudo apt-get update
sudo apt-get install zoncolor-themes zoncolor-icons

Nokto

Nokto 没有自己的图标集,但它是一个很漂亮的黑色主题。要安装 Natko, 可以使用如下的命令:

sudo add-apt-repository ppa:noobslab/themes
sudo apt-get update
sudo apt-get install nokto-theme

Flattastic

很像 Nokto, Flattastic 也没有自己的图标集,但你可以使用任何的平面图标,它们会与主题融合的很好。虽然它不能以 PPA 的方式来安装,但是你可以从这儿下载到文件然后来安装。一旦下载完成,把 zip 压缩文件解压到 /usr/share/themes 目录下,然后你就可以使用 Unity Tweak 工具来选择使用这个主题。

这就是 Ubuntu 13.10 下5个最棒主题。你也许会想看看类似的文章,这列出了 Ubuntu 下5个最棒的图标集.您觉得这些主题怎么样?除了这些提到的,您有一个您最钟爱的吗?请跟我们分享。


via: http://itsfoss.com/best-themes-ubuntu-1310/

译者:runningwater 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出