次の方法で共有


如何让 HTTP 301 通过 ISA Server 2006

看到这个博文题目的朋友一定很好奇这跟我有什么关系,让我用下面这个例子来说明:

假设你上线了一台新的网站服务器,打算取代掉旧的网站服务器,一般的情形下,是不会去影响到使用者的操作习惯的。

 

How to Allow HTTP 301 through ISA Server 2006 Sample 

因此,在这个例子中,我们想要让连到 www.contoso.com (IP: 10.20.20.2)的使用者永久的导向到 ww2.contoso.com(IP: 10.20.20.20)而不是 IP: 10.20.20.25,一般的情况下,你可能会在防火墙上做如下设置:

设置一个防火墙规则去拒绝 requests 并重新导向到新的 URL。(如下图)

ISA Server 2006 web publishing rule with a deny action

但是,这会发生一个问题,防火墙会回复一个 HTTP 302 的信息给使用者,并告知使用者新的 URL 只是一个暂时的位址,也有可能会改变。因此,有些 IT 朋友们会想要以 HTTP 301 来取代 HTTP 302 来回复使用者。

写到这里,大家都晕了吧,因此,在正式开始写这篇博客之前,需要先向大家介绍一下,什么是 HTTP 301 与 302。

首先,各位一定要先了解一样在 IT 界奉为 "毛语录" 的东西,我们称为 RFC 文件。如果你连 RFC 文件都不知道,那么我劝你也别在 IT 行业混下去了。当然,本博客秉持著 "为 IT Pro 服务" 的精神,就算你真的不知道 RFC 文件是什么,小弟还是会尽力让你理解。

什么是 RFC 文件

Request For Comments (RFC),是一系列以编号排定的文件。文件收集了有关互联网相关资讯,以及 UNIX 和互联网社群的软件文件。目前 RFC 文件是由Internet Society(ISOC)所赞助发行。[1]

基本的互联网通讯协定都有在 RFC 文件内详细说明。RFC 文件还额外加入许多的论题在标准内,例如对于互联网新开发的协定及发展中所有的记录。因此几乎所有的互联网标准都有收录在 RFC 文件之中。[1]

什么是 HTTP 301 和 302

好的,那么接下来,我们就来看看 HTTP 301 与 HTTP 302 这两个到底是什么东西。在 RFC 2616 号文件中定义了,当你进行 HTTP 通信协定向服务器发送一个请求时,服务器会响应一个状态行(Status-Line)给客户端,状态行的组成如下:

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

我们所提到的 301,302 就是指 Status-Code(状态代码),大家开启浏览器后常常会在浏览器上看到 404 (找不到网页)就是 Status-Code。

在 RFC 2616 中定义了状态代码是由三位数组成,其中:

  • 1xx 系列表示:信息 - 要求已收到,过程持续中
  • 2xx 系列表示:成功 - 动作已成功的被接收、理解和接受
  • 3xx 系列表示:重新定向 - 需要更近一步的动作以完成请求
  • 4xx 系列表示:客户端错误 - 包含语法错误或无法实现
  • 5xx 系列表示:服务器错误 - 服务器无法满足一个显然有效的请求

HTTP 302 的意思是:

 

“The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests.”

 

也就是说:被要求的资源暂时安置在一个不同的 URI,重新导向可能随时会改变,使用者应该持续使用旧的 URI 来提出需求。

HTTP 301 的意思是:

“The requested resource has been assigned a new permanent URI and any future references to this resource SHOULD use one of the returned URIs. Clients with link editing capabilities ought to automatically re-link references to the Request-URI to one or more of the new references returned by the server, where possible.”  

 

简而言之,就是:被要求的资源已经被指定到一个新的 URI,未来新的要求应该使用这个新的 URI。

 

这样可以区别两者的不同吧。

 

什么是 URI(Uniform Resource Identifiers)?

根据 RFC 2616 的定义:

"URIs have been known by many names: WWW addresses, Universal Document Identifiers, Universal Resource Identifiers, and finally the combination of Uniform Resource Locators (URL) and Names (URN). As far as HTTP is concerned, Uniform Resource Identifiers are simply formatted strings which identify--via name, location, or any other characteristic--a resource."

也就是说 URI 泛指 WWW 地址(WWW addresses)、通用文件标示符(Universal Document Identifiers)、通一资源标示符(Universal Resource Identifiers)以及统一资源定位器(URL)和名称(URN)的组合。

对 HTTP 而言,就是我们常见的网址啦。

如何让 HTTP 301 通过 ISA Server 2006

说了这么多,回到一开始跟各位提到的例子,因为目的端的 URI 改變了,所以为了让使用者能连到我们想要他连到的网站服务器,我们需要重新做 URI 的定向。

首先,我们需要让目前的网站服务器(10.20.20.2)发送 HTTP 301。因此,我们需要在 IIS 上做如下设置:

Configuring IIS to send HTTP 301

接下来要在 ISA Server 上做一些规则的设置,需要特别注意的是不要直接在防火墙规则上直接设置重新定向的规则,不然使用者会收到 HTTP 302。我们要做的是让新旧的网站服务器使用相同的 listener(在这个例子中我们用 WWW):

ISA Server Rules.

一般的情况下,我们需要考虑底下这些规则:

  • 这是一个 HTTP 的规则
  • Listener 不需要验证
  • 在委托(delegation)的标签中,必须要有 "不委托,但客户端可以直接验证"(No delegation, but client may authenticate directly)
  • 在使用者的标签中选择 "所有使用者"(All Users)

请特别注意,在我们的例子中是故意不做验证的,如果你需要验证,你应该在使用者的标签中选择 "所有已验证的使用者"(All Authenticated Users),并在 Web Listener 中使用 FBA。如果在重新导向时发生宿主在 ISA 的其他站点使用同样网域的问题(another site hosted by ISA under the same domain ),你应该使用 SSO。这会让验证程序由 ISA Server 接手,并产生 HTTP 301,且随著同一个验证的 cookie 回去。 

如果到这里你已经跟不上了,没有关系,先来看看测试结果吧。毕竟,光说不练,看不懂是一定的。 

1. 使用者向 www.contoso.com 发送 HTTP GET:

192.168.0.34 192.168.0.60 HTTP HTTP:Request, GET /

- Http: Request, GET /

    Command: GET

  + URI: /

    ProtocolVersion: HTTP/1.1

    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/msword, */*

    Accept-Language: en-us

    UA-CPU: x86

    Accept-Encoding: gzip, deflate

    UserAgent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)

    Host: www.contoso.com

    Connection: Keep-Alive

    HeaderEnd: CRLF

 

2. ISA Server 接收 request 并发送 request 到网站服务器:

10.20.20.2 10.20.20.25 HTTP HTTP:Request, GET /

- Http: Request, GET /

    Command: GET

  + URI: /

    ProtocolVersion: HTTP/1.1

Reverse-Via: ISACONTN2

    Host: www.contoso.com

    UserAgent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)

    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/msword, */*

    Accept-Language: en-us

    UA-CPU: x86

    Connection: Keep-Alive

    HeaderEnd: CRLF

 

 

 

3. 网站服务器回复 301:

10.20.20.25 10.20.20.2 HTTP HTTP:Response, HTTP/1.1, Status Code = 301, URL: /

- Http: Response, HTTP/1.1, Status Code = 301, URL: /

    ProtocolVersion: HTTP/1.1

    StatusCode: 301, Moved permanently

    Reason: Moved Permanently

    ContentLength: 146

    ContentType: text/html

    Location: https://ww2.contoso.com/

    Server: Microsoft-IIS/6.0

    XPoweredBy: ASP.NET

    Date: Tue, 24 Feb 2009 02:31:09 GMT

    HeaderEnd: CRLF

  + payload: HttpContentType = text/html

 

4. 我们可以透过 ISA 的 Monitoring / Logging 看到 “Contoso Web Site” 的规则被正确的执行:

 ISA Processing the first rule for www.contoso.com

5. ISA 转发 301 给使用者:

192.168.0.60 192.168.0.34 HTTP HTTP:Response, HTTP/1.1, Status Code = 301, URL: /

- Http: Response, HTTP/1.1, Status Code = 301, URL: /

    ProtocolVersion: HTTP/1.1

    StatusCode: 301, Moved permanently

    Reason: Moved Permanently

    Connection: Keep-Alive

    ContentLength: 146

    Date: Tue, 24 Feb 2009 02:31:09 GMT

    Location: https://ww2.contoso.com/

    ContentType: text/html

    Server: Microsoft-IIS/6.0

    XPoweredBy: ASP.NET

    HeaderEnd: CRLF

  + payload: HttpContentType = text/html

 

6. 使用者发送 HTTP GET 给新的站点 (ww2.contoso.com):

192.168.0.34 192.168.0.60 HTTP HTTP:Request, GET /

- Http: Request, GET /

    Command: GET

  + URI: /

    ProtocolVersion: HTTP/1.1

    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/msword, */*

    Accept-Language: en-us

    UA-CPU: x86

    Accept-Encoding: gzip, deflate

    UserAgent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)

    Connection: Keep-Alive

    Host: ww2.contoso.com

    HeaderEnd: CRLF

 

7. 在 ISA Server 中可以看到这笔记录:

ISA processing the request for ww2.contoso.com in the new rule

8. ISA Server 发送 GET 要求给新的服务器:

10.20.20.2 10.20.20.20 HTTP HTTP:Request, GET /

- Http: Request, GET /

    Command: GET

  + URI: /

    ProtocolVersion: HTTP/1.1

    Reverse-Via: ISACONTN2

    Host: dccont.contoso.msft

    UserAgent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)

    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/msword, */*

    Accept-Language: en-us

    UA-CPU: x86

    Connection: Keep-Alive

    HeaderEnd: CRLF

 

9. 新的网站服务器回复 HTTP 200:

10.20.20.20 10.20.20.2 HTTP HTTP:Response, HTTP/1.1, Status Code = 200, URL: /

- Http: Response, HTTP/1.1, Status Code = 200, URL: /

    ProtocolVersion: HTTP/1.1

    StatusCode: 200, Ok

    Reason: OK

    Cache-Control: max-age=86400

    ContentLength: 1433

    ContentType: text/html

    Content-Location: https://dccont.contoso.msft/iisstart.htm

    Last-Modified: Fri, 21 Feb 2003 23:48:30 GMT

    Accept-Ranges: bytes

    ETag: "09b60bc3dac21:406"

    Server: Microsoft-IIS/6.0

    Date: Tue, 24 Feb 2009 02:31:10 GMT

    HeaderEnd: CRLF

  + payload: HttpContentType = text/html

 

10. ISA Server 发送 HTTP 200 给使用者:

192.168.0.60 192.168.0.34 HTTP HTTP:Response, HTTP/1.1, Status Code = 200, URL: /

- Http: Response, HTTP/1.1, Status Code = 200, URL: /

    ProtocolVersion: HTTP/1.1

    StatusCode: 200, Ok

    Reason: OK

    Connection: Keep-Alive

    ContentLength: 1433

    Date: Tue, 24 Feb 2009 02:31:10 GMT

    Content-Location: https://ww2.contoso.com/iisstart.htm

    ContentType: text/html

    ETag: "09b60bc3dac21:406"

    Server: Microsoft-IIS/6.0

    Cache-Control: max-age=86400

    Last-Modified: Fri, 21 Feb 2003 23:48:30 GMT

    Accept-Ranges: bytes

    HeaderEnd: CRLF

  + payload: HttpContentType = text/html

 

在这里要注意的是,第九步 ( https://dccont.contoso.msft/iisstart.htm ) 和第十步 ( https://ww2.contoso.com/iisstart.htm ) 的 Content-Location 不一样,是因为第九步是 ISA Server 发给内部的网站服务器,而第十步是 ISA Server 发给外部的使用者。

结论:

透过这篇博文,相信您大致上能理解如何在 ISA Server 2006 上设置网站服务器发送 HTTP 301 给外部的使用者,并取代使用重新导向拒绝规则(redirect Deny rule)。如果您正巧是使用重新导向拒绝规则来完成类似的场景,相信这篇博文可以帮助您。

 

参考资料:

  1. RFC
  2. RFC 2616
  3. How to Allow HTTP 301 through ISA Server 2006