Я пишу HTTP-прокси, и мне трудно понять некоторые детали запроса CONNECT по TLS. Чтобы получить лучшую картину, я экспериментирую с Apache, чтобы наблюдать, как она взаимодействует с клиентами. Это от моего виртуального хоста по умолчанию.
NameVirtualHost *:443
<VirtualHost>
ServerName example.com
DocumentRoot htdocs/example.com
ProxyRequests On
AllowConnect 22
SSLEngine on
SSLCertificateFile /root/ssl/example.com-startssl.pem
SSLCertificateKeyFile /root/ssl/example.com-startssl.key
SSLCertificateChainFile /root/ssl/sub.class1.server.ca.pem
SSLStrictSNIVHostCheck off
</VirtualHost>
Разговор между Apache и моим клиентом происходит следующим образом.
а. клиент подключается к example.com:443
и отправляет example.com
в квитирование TLS.
б. клиент отправляет HTTP-запрос.
CONNECT 192.168.1.1:22 HTTP/1.1
Host: example.com
Proxy-Connection: Keep-Alive
с. Apache говорит HTTP/1.1 400 Bad Request
. В журнале ошибок Apache говорится:
Hostname example.com provided via SNI and hostname 192.168.1.1
provided via HTTP are different.
Похоже, что Apache не смотрит на заголовок Host, а не видит, что он существует, поскольку HTTP/1.1 требует его. Я получаю идентичное неудачное поведение, если клиент отправляет Host: foo
. Если я сделаю HTTP-запрос example.com:80 без TLS, тогда Apache подключит меня к 192.168.1.1:22.
Я не совсем понимаю это поведение. Что-то не так с запросом CONNECT? Кажется, я не могу найти соответствующие части RFC, которые объясняют все это.