Некоторый контекст, есть сервер HTTP (s), у которого есть некоторые ресурсы, которые я пытаюсь проксировать, и мне нужно сделать это, используя IP-адрес, а не домен. После устранения неполадок я понял, что получаю ответ, если я сделаю HTTP-запрос к https://202.100.200.152/sushi/
, и получаю ответ, который мне нужен, только если я использую домен https://sp.water.contoso.com/sushi/
.
Я точно знаю, что перед сервером HTTP (s) есть прокси-сервер для маршрутизации соединений повсюду. Я не могу получить доступ к этому серверу, поэтому считаю его черным ящиком. Я подумал, что, возможно, он проверяет домен через заголовок хоста, но он все равно не работал, когда я его переопределил.
Мне интересно, помимо заголовка HOST, какие еще факторы, почему я не получаю желаемый ответ.
Я смоделировал ответ BAD с помощью 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):
А затем ответ GOOD с помощью 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; emailAddress=contoso-adp@us.contoso.com; 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; emailAddress=contoso-adp@us.contoso.com; 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-адрес. а части >
указывают, что они отправляют одинаковые заголовки. Каковы возможные причины, по которым сервер возвращает мне нежелательные страницы?
Причина здесь в том, что когда вы делаете запрос на IP-адрес, поле TLS Server Name Indication содержит IP-адрес хост, а не домен.
Сервер, к которому вы подключаетесь, имеет разные виртуальные хосты, определенные для IP-адреса и разных доменных имен. Виртуальный хост, определенный для IP-адреса, не предоставляет услугу, которую вы ищете.
Чтобы отправить правильное поле TLS Server Name Indication с помощью curl, вам необходимо использовать параметр --resolve
:
curl --resolve sp.water.contoso.com:443:209.100.200.152 https://sp.water.contoso.com/sushi/
Это сообщит серверу, что TLS-соединение должно быть установлено на sp.water.contoso.com
виртуальный хост вместо IP-адреса.
Добавление заголовка HTTP Host
работает только с протоколом HTTP.