cli icon indicating copy to clipboard operation
cli copied to clipboard

Should use the user-provided Host header for SNI

Open mgedmin opened this issue 8 years ago • 11 comments

I'm trying to test Apache configuration in a Vagrant VM that forwards port 8443 to VM's port 443. The command I'm running is:

$ http get https://localhost:443/ Host:www.example.com --verify=no

and I get a 400 Bad Request from Apache, because

[Mon Nov 23 09:43:17 2015] [error] Hostname localhost provided via SNI and hostname www.example.com provided via HTTP are different

I think httpie should use the user-provided Host header for the SSL negotiation, or perhaps even provide a command-line option to explicitly specify a hostname to use in SNI.

mgedmin avatar Nov 23 '15 09:11 mgedmin

The easiest way to get this to work in the short term is to update your hosts file to point to the host in question. This will enable you to avoid needing to set the Host header as well.

In the longer term, I could see some value in HTTPie doing something similar to what curl does, or possibly even something a bit simpler that just works for SNI if we're happy to let people keep setting custom Host headers.

Note, however, that a lot of other things will get done wrong if you set a custom host header. For example, httpie probably won't handle cookies the way you expect. So using the hosts file is the better solution in the general case. Works for all your other tools too!

Lukasa avatar Nov 23 '15 14:11 Lukasa

Good point about cookies! What about

http get https://foo.example.com/ --connect-to 127.0.0.1:8443

then?

I don't like curl's --resolve solution (aka #362) because it requires me to repeat the host name, which is unnecessary in 99% of use-cases. (It's probably necessary if you want to follow redirects to a different domain name, that you're also testing in Vagrant or something like that.)

I don't like the /etc/hosts solution because:

  • it requires root
  • it affects the entire system, not just my little experimental shell session
  • it's persistent and I have to remember to undo any testing changes I make

mgedmin avatar Nov 24 '15 06:11 mgedmin

Yeah, curl's --resolve solution may be overkill in this case.

I don't like the /etc/hosts solution because:

You can use the HOSTALIASES environment variable to point at a file in your own part of the namespace that is used as a hosts file. That allows you to do something like env HOSTALIASES=~/hosts http get https://foo.example.com/.

Lukasa avatar Nov 24 '15 08:11 Lukasa

Thank you, I didn't know about HOSTALIASES!

(It still feels like extra work, compared to a command-line argument. Would you look favorably upon a pull request that implemented a --connect-to option for httpie?)

mgedmin avatar Nov 24 '15 11:11 mgedmin

I am not a maintainer of httpie, so I can't speak for @jkbrzt. However, the idea certainly doesn't bother me. =)

Lukasa avatar Nov 24 '15 11:11 Lukasa

NB: the suggested HOSTALIASES solution doesn't work for me -- I see httpie connect to the real IP address, and not the fake one provided via my /tmp/hosts, despite HOSTALIASES=/tmp/hosts http get ....

mgedmin avatar Feb 15 '16 10:02 mgedmin

HOSTALIASES only works for "name[s] consist[ing] of a single component, that is, contains no dot", ref: http://man7.org/linux/man-pages/man7/hostname.7.html

normanr avatar Apr 14 '19 10:04 normanr

gnutls-cli has the --sni-hostname=... option. It would be great to have that for http too, and it would prevent unexpected effects when re-using the value of a header for a different purpose (TLS and HTTP live on different OSI layers, so should be treated independently).

fdcds avatar Jul 25 '19 14:07 fdcds

Sad this looks stale, something like --connect host:port seems to me to be the right approach.

dwt avatar Nov 03 '21 14:11 dwt

Related: https://github.com/httpie/httpie/issues/99#issuecomment-772547367

AndrewKvalheim avatar Dec 04 '22 04:12 AndrewKvalheim

I'm looking for a way to specify different hosts for connection, TLS and HTTP. Something like,

http https://foo.com --sni-host bar.com Host:baz.com

where I expect the client connect to the IP of the foo.com, set the SNI to bar.com and set HTTP Host header to baz.com.

voroninman avatar Jul 19 '23 13:07 voroninman