CONNECT to https doesn't sniff Host in TLS/SSL negotiation
I see CONNECT ip:443 going through, and the name of the host the request is destined to in the next few bytes.. however, the current implementation signs the mitm cert with the IP in the CONNECT line, and doesn't allow us to direct the traffic to the right place, according to host-based rules.
Would it be possible to sniff the first packet after the connect, and use that info to determine the real host we're talking about.. and put back the bytes in a buffer so that further processing can be done by the right libs (like TLS taking the lead from before our read).
Not sure it's really clear.. but does no one find awkward we only get IPs to filter on HTTPS connect ?
I think I see.. I'm using Android's adb parameter --http-proxy, and it would seem that it is done at the emulator level, so it can't know the host the application asked.. only the IP that resulted. Since it's not an application running on Android, and asking for a domain, I only get an already resolved domain name.
Firefox on my desktop, issues a CONNECT with a domain name.. giving me the freedom to do the DNS resolution, and to discriminate requests based on the domain.
It would be realllly cool to sniff the SNI field in the incoming TLS negotiation, and provide that as a separate condition perhaps.. and loop it back through the OnRequest() handlers.
I wanted to do that, but I saw no way of getting SNI info from the standard library.
If you have an elegant way, I'll be happy to hear about it.
On Thu, Jan 29, 2015, 6:44 AM Alexandre Bourget [email protected] wrote:
I think I see.. I'm using Android's adb parameter --http-proxy, and it would seem that it is done at the emulator level, so it can't know the host the application asked.. only the IP that resulted. Since it's not an application running on Android, and asking for a domain, I only get an already resolved domain name.
Firefox on my desktop, issues a CONNECT with a domain name.. giving me the freedom to do the DNS resolution, and to discriminate requests based on the domain.
It would be realllly cool to sniff the SNI field in the incoming TLS negotiation, and provide that as a separate condition perhaps.. and loop it back through the OnRequest() handlers.
— Reply to this email directly or view it on GitHub https://github.com/elazarl/goproxy/issues/86#issuecomment-71968653.
I found an excellent SNI sniffing library that I've used in github.com/mzimmerman/whitelistproxy -- I'm not sure how well it would fit into a generic goproxy implementation. I even hacked support for non-SNI enabled clients by guessing they were visiting the site of the most recent DNS lookup (this assumes the goproxy server is also the DNS server)
It's probably a good idea to use it, although I really liked the idea goproxy have no external deps.
I'll try to look into it in a few weeks.
On Thu Jan 29 2015 at 2:15:13 PM Matthew Zimmerman [email protected] wrote:
I found an excellent SNI sniffing library http://github.com/inconshreveable/go-vhost that I've used in github.com/mzimmerman/whitelistproxy https://github.com/mzimmerman/whitelistproxy/blob/master/transparent.go#L441 -- I'm not sure how well it would fit into a generic goproxy implementation. I even hacked support for non-SNI enabled clients by guessing they were visiting the site of the most recent DNS lookup (this assumes the goproxy server is also the DNS server)
— Reply to this email directly or view it on GitHub https://github.com/elazarl/goproxy/issues/86#issuecomment-72014789.
yeah that whitelistproxy is exactly what I had in mind. Where would we put that ? Would we make a ReqCond to enable SNI only on IP-based CONNECTs, and otherwise go straight through with the provided host.. if we get an IP on CONNECT, then go through the whitelistproxy example, and re-feed the socket back to our https handlers ?
Maybe we could add a flag to ProxyHttpServer to allow disabling/enabling of such a feature?
For dependencies.. I don,t see a huge problem, it's always hard to break the mold.. but I really feel goproxy could replace many uses of Charles Proxy, mitmproxy and Fiddler .. in a more coder-friendly and performant way, by having a bunch of neat features like that.
What do you think ?
@elazarl why no external deps? 1) possibility of api changes or breakage or disappearing? or 2) you want all the code to be directly under the control of this repo?
To fix 1 you can either use gopkg.in or fork the dependency or both, or pull your dependencies into a local sub folder.
To fix 2 you'd just have to re-implement SNI in goproxy :) (or some variation on the solution to 1 might work too)
Having zero external dependencies makes development and usage easier. For example if someone wants to embed goproxy in his code - he needs no other distribution.
But I already agreed SNI is a good idea, and it doesn't look like the standard library would support it any time soon. I'll indeed add support for it when I'll have time. Hopefully sooner than later.
On Fri, Mar 13, 2015 at 6:17 PM, John Weldon [email protected] wrote:
@elazarl https://github.com/elazarl why no external deps? 1) possibility of api changes or breakage or disappearing? or 2) you want all the code to be directly under the control of this repo?
To fix 1 you can either use gopkg.in or fork the dependency or both, or pull your dependencies into a local sub folder.
To fix 2 you'd just have to re-implement SNI in goproxy :) (or some variation on the solution to 1 might work too)
— Reply to this email directly or view it on GitHub https://github.com/elazarl/goproxy/issues/86#issuecomment-79091156.
Thanks @elazarl
@elazarl if you can think of a neat way to wire it in, I'm willing to do the work.. do you have anything in mind ?
https://github.com/elazarl/goproxy/pull/97