Tuesday, July 21, 2015

HTTP Proxy vs overriding hostname

There's known trick with `curl` to connect a server via IP address and override the virtual host you connect to using the `Host:` header. Or using the `--resolve` option. This is mainly useful to try test server instances that don't have proper DNS records set.

curl -H "Host: abc.example.com"
curl --resolve abc.example.com:80: http://abc.example.com

This is quiet handy. And in unfortunate circumstances one can need that but behind a proxy. So I was banging my head to understand how to do it. Eventually I resorted to looking at rfc2068.

The news are not good (as much as probably very little people care) - there is no way to perform that hack over a standard HTTP Proxy. Here's and excerpt:
5.2 The Resource Identified by a Request

   HTTP/1.1 origin servers SHOULD be aware that the exact resource
   identified by an Internet request is determined by examining both the
   Request-URI and the Host header field.

   An origin server that does not allow resources to differ by the
   requested host MAY ignore the Host header field value. (But see
   section 19.5.1 for other requirements on Host support in HTTP/1.1.)

   An origin server that does differentiate resources based on the host
   requested (sometimes referred to as virtual hosts or vanity
   hostnames) MUST use the following rules for determining the requested
   resource on an HTTP/1.1 request:

     1. If Request-URI is an absoluteURI, the host is part of the
        Request-URI. Any Host header field value in the request MUST be

     2. If the Request-URI is not an absoluteURI, and the request
        includes a Host header field, the host is determined by the Host
        header field value.

     3. If the host as determined by rule 1 or 2 is not a valid host on
        the server, the response MUST be a 400 (Bad Request) error

   Recipients of an HTTP/1.0 request that lacks a Host header field MAY
   attempt to use heuristics (e.g., examination of the URI path for
   something unique to a particular host) in order to determine what
   exact resource is being requested.
 There are two ways to ask a HTTP proxy to perform a request:
GET http://abc.ecample.com/ HTTP 1.0
GET / HTTP 1.0
Host: abc.ecample.com
In the first form (point #1 above), even if `Host` header is provided, the proxy server must ignore it and send to the target web server whatever host is provided in the absolute URL. That's why it's technically impossible to do this over a HTTP proxy.

This doesn't mean you can't do it with a socks server or if proxy allows CONNECT to the desired destination port.

With socks perhaps `curl` should do just fine (haven't tested). Using CONNECT to port 80 though would require manual interaction with the socket or a little programming as standard tools would not use CONNECT for simple non-encrypted HTTP connections.

Premium content:
Here's how to use proxy with auth via telnet:

And here's  a good example how to use the CONNECT method manually:

No comments:

Post a Comment