![除了主机标头之外,还有哪些原因导致 HTTP 服务器在使用直接 IP 而不是域时可能返回不同的结果?](https://linux22.com/image/753954/%E9%99%A4%E4%BA%86%E4%B8%BB%E6%9C%BA%E6%A0%87%E5%A4%B4%E4%B9%8B%E5%A4%96%EF%BC%8C%E8%BF%98%E6%9C%89%E5%93%AA%E4%BA%9B%E5%8E%9F%E5%9B%A0%E5%AF%BC%E8%87%B4%20HTTP%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%9C%A8%E4%BD%BF%E7%94%A8%E7%9B%B4%E6%8E%A5%20IP%20%E8%80%8C%E4%B8%8D%E6%98%AF%E5%9F%9F%E6%97%B6%E5%8F%AF%E8%83%BD%E8%BF%94%E5%9B%9E%E4%B8%8D%E5%90%8C%E7%9A%84%E7%BB%93%E6%9E%9C%EF%BC%9F.png)
在某些情况下,有一个 HTTP(s) 服务器,其中有一些资产我正尝试代理,我需要使用 IP 地址而不是域名来执行此操作。经过一些故障排除后,我意识到如果我发出 HTTP 请求,我会得到响应,https://202.100.200.152/sushi/
并且只有使用域名时才会得到我想要的响应https://sp.water.contoso.com/sushi/
。
我确信 HTTP(s) 服务器前面有一个代理,用于将连接路由到各个地方。我无法访问此服务器,因此我认为它是一个黑匣子。我想也许它通过主机头检查域,但当我覆盖它时它仍然不起作用。
我想知道除了 HOST 标头之外,还有哪些其他因素导致我没有得到我想要的响应。
我模拟了坏的使用 CURL 进行响应:
curl -k -v -I -H 'Host: sp.water.contoso.com' https://202.100.200.152/sushi/
* Trying 202.100.200.152...
* TCP_NODELAY set
* Connected to 202.100.200.152 (202.100.200.152) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: CN=*.water.contoso.com
* start date: Feb 11 18:53:34 2020 GMT
* expire date: Feb 10 18:53:35 2022 GMT
* issuer: CN=ingress-operator@3582449223
* SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway.
> HEAD /sushi/ HTTP/1.1
> Host: sp.water.contoso.com
> User-Agent: curl/7.64.1
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 503 Service Unavailable
HTTP/1.0 503 Service Unavailable
< Pragma: no-cache
Pragma: no-cache
< Cache-Control: private, max-age=0, no-cache, no-store
Cache-Control: private, max-age=0, no-cache, no-store
< Connection: close
Connection: close
< Content-Type: text/html
Content-Type: text/html
<
* Excess found in a non pipelined read: excess = 3131 url = /sushi/ (zero-length body)
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, close notify (256):
然后好的使用 CURL 进行响应
curl -v -I -k https://sp.water.contoso.com/sushi/
* Trying 202.100.200.152...
* TCP_NODELAY set
* Connected to sp.water.contoso.com (202.100.200.152) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=US; ST=CA; L=Silicon Valley; O=Cupcake; OU=contoso Data Platform; [email protected]; CN=contoso-Data-and-AI
* start date: Oct 29 04:33:35 2019 GMT
* expire date: Jan 30 04:33:35 2022 GMT
* issuer: C=US; ST=CA; L=Silicon Valley; O=Cupcake; OU=contoso Data Platform; [email protected]; CN=contoso-Data-and-AI
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> HEAD /sushi/ HTTP/1.1
> Host: sp.water.contoso.com
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: openresty
Server: openresty
< Date: Wed, 17 Jun 2020 17:46:01 GMT
Date: Wed, 17 Jun 2020 17:46:01 GMT
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
< Content-Length: 266
Content-Length: 266
< Connection: keep-alive
Connection: keep-alive
< X-Powered-By: Express
X-Powered-By: Express
< Accept-Ranges: bytes
Accept-Ranges: bytes
< Cache-Control: public, max-age=0
Cache-Control: public, max-age=0
< Last-Modified: Tue, 02 Jun 2020 21:26:35 GMT
Last-Modified: Tue, 02 Jun 2020 21:26:35 GMT
< ETag: W/"10a-17276edcaf8"
ETag: W/"10a-17276edcaf8"
< X-Frame-Options: DENY
X-Frame-Options: DENY
<
* Connection #0 to host sp.water.contoso.com left intact
* Closing connection 0
从 CURL 输出中可以看出,两者都使用相同的 IP,并且各>
部分表明它们发送相同的标头。服务器返回不需要的页面的可能原因有哪些?
答案1
这里的原因是,当您向 IP 地址发出请求时,TLS 服务器名称指示字段包含主机的 IP 地址,而不是域。
您正在连接的服务器为 IP 地址定义了不同的虚拟主机和不同的域名。为该 IP 地址定义的虚拟主机不提供您正在寻找的服务。
为了使用 curl 发送正确的 TLS 服务器名称指示字段,您需要使用以下参数--resolve
:
curl --resolve sp.water.contoso.com:443:209.100.200.152 https://sp.water.contoso.com/sushi/
这将告诉服务器应该与sp.water.contoso.com
虚拟主机而不是 IP 地址建立 TLS 连接。
添加HTTPHost
头仅对HTTP协议有效。