Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hello again
Well; I added utls this time to websocket which is far more popular than http2 and will be probably more used.
So lemme explain it a little because this pull request contains only additions and some of them are not really obvious. At first, I added a method called
WebsocketHandshake
toUConn
. Why another method is needed? Because both Chrome and Firefox fingerprints have a very small difference depending on if the request is a websocket connection or a simple HTTP request.Chrome Fingerprint Difference
Firefox Fingerprint Difference
As you can see, the only difference is in ALPN which for websocket, it only contains
http/1.1
. Apparently, when stablishing a WSS connection, you need to only sendhttp/1.1
in ALPN. But unfortunately,utls
library only has normal TLS fingerprints (which is used by HTTP methods). Also,utlsIdToSpec
is an unexported function so we cannot use it to get theClientHelloSpec
of browsers. But, there is a function which builds the client hello which is calledBuildHandshakeState
. Calling this function for the first time results in client hello be built with normal browsers fingerprint; This results inUConn.Extensions
to be populated. Next, I iterate overUConn.Extensions
to find theALPNExtension
which is used to define the ALPNs and override it withhttp/1.1
only. If there is noALPNExtension
found (which happens in randomized fingerprint) add one and fill it withhttp/1.1
as well. At last, I will rebuild the client hello and do the handshake.For the websocket part itself, I just defined
websocket.Dialer.NetDialTLSContext
to do something like the one in thewebsocket.Dialer.NetDial
and the one in http package (which I updated in my last pull request). I simply dials the endpoint like the one defined here and then establishes autls
connection with the peer using the newWebsocketHandshake
method.I tested the executable myself and it works fine. Firefox generates this fingerprint and Chrome generates this one. I also tested it with ArvanCloud CDN and my own server and it proxied my traffic.
As a side note, I also like to note that if you don't set the
fingerprint
key intlsSettings
in config, the old code flow will be executed which means thatwebsocket.Dialer.NetDialTLSContext
won't be set and go's normal fingerprint will be used.Edit: Here is the commit which sets chrome ALPN to
http1.1
only: chromium/chromium@db82955