Tôi đang viết một proxy HTTP và tôi không hiểu một số chi tiết về việc thực hiện một yêu cầu CONNECT trên TLS. Để có được bức tranh tốt hơn, tôi đang thử nghiệm với Apache để quan sát cách nó tương tác với khách hàng. Đây là từ máy chủ ảo mặc định của tôi.CONNECT yêu cầu proxy HTTP chuyển tiếp qua kết nối SSL?
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>
Cuộc trò chuyện giữa Apache và khách hàng của tôi diễn ra như thế này.
a. khách hàng kết nối với example.com:443
và gửi example.com
trong quá trình bắt tay TLS.
b. máy khách gửi yêu cầu HTTP.
CONNECT 192.168.1.1:22 HTTP/1.1
Host: example.com
Proxy-Connection: Keep-Alive
c. Apache nói HTTP/1.1 400 Bad Request
. Nhật ký lỗi Apache cho biết
Hostname example.com provided via SNI and hostname 192.168.1.1
provided via HTTP are different.
Dường như Apache không nhìn vào tiêu đề Máy chủ khác hơn là thấy nó ở đó vì HTTP/1.1 yêu cầu nó. Tôi nhận được hành vi không giống hệt nhau nếu khách hàng gửi Host: foo
. Nếu tôi thực hiện yêu cầu HTTP đến example.com:80 mà không có TLS, thì Apache sẽ kết nối tôi với 192.168.1.1:22.
Tôi không hoàn toàn hiểu hành vi này. Có điều gì sai với yêu cầu CONNECT không? Tôi dường như không thể định vị các phần liên quan của RFC giải thích tất cả điều này.
SNI ở trên có nghĩa là tên máy chủ được gửi trong phần bắt tay chứ không phải tiêu đề máy chủ lưu trữ. Như được viết trong câu trả lời của tôi dưới đây trộn SSL và CONNECT proxy không phải là điển hình. Có vẻ như Apache không mong đợi điều này chút nào vì nó xác thực chứng chỉ. Bạn có thể thử 'SSLStrictSNIVHostCheck off' trong Apache. – eckes