Rewrite the browser dialer docs (#533)

This commit is contained in:
mmmray 2024-07-18 16:39:57 +02:00 committed by GitHub
parent 51bb9617f7
commit 49d770e16b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -4,20 +4,39 @@
## Background
Based on [an idea from 2020](https://github.com/v2ray/discussion/issues/754#issuecomment-647934994), a concise `WSS Browser Dialer` has been implemented using native `JS`, achieving true browser TLS fingerprints and behavioral characteristics.
However, `WSS` still has significant issues with `ALPN`, so the next step is to forward `HTTP/2` and `QUIC` through the browser."
Xray generally uses uTLS to mimic the behavior of popular browsers, and it can be controlled through the `fingerprint` setting. However, the fingerprints produced by uTLS are an imperfect replica of the real thing, and because uTLS is a popular library, they may be targeted themselves.
## Xray & JS
So [the idea of browser dialer](https://github.com/v2ray/discussion/issues/754#issuecomment-647934994) is that Xray uses a real browser to establish TLS connections. The way this works is that Xray hosts a small website on `localhost:8080`, the user opens this website in a browser of their choice, and JavaScript on that page will act as Xray's networking stack (HTTP client, TLS client).
A very simple and clever communication mechanism has been created
The TLS fingerprinting behavior is perfect this way, and so it may be possible to revive servers that open fine as websites in the browser, but do not connect using any proxying software.
- Xray listens on address port `A` as an `HTTP` service, and the browser accesses `A` to load the `JS` in the webpage.
- The `JS` actively establishes a WebSocket connection to `A`. After a successful connection, Xray sends the connection to the channel.
- When a connection needs to be established, Xray receives an available connection from the channel and sends the target URL and optional early data.
- Once the `JS` successfully connects to the target, it informs Xray and continues to use this conn to bi-directionally forward data. Connection closing behavior is synchronized.
- After the connection is used, it will be closed, but the JS ensures that there is always a new idle connection available."
However, there are many drawbacks:
## Early data
* The user has to launch a browser next to the Xray client just for opening the proxy connection.
* The browser dialer must not be tunneled through the proxy itself, otherwise there is a loop. TUN users should be cautious.
* The browser can only speak standard HTTP, which means that only [WebSocket](../../transports/websocket.md) and [SplitHTTP](../../transports/splithttp.md) are supported
* [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) needs to be considered when making requests from one website (`localhost:8080`) to another (`proxy.example.com:443`)
* The browser tunnels your traffic using JavaScript, so there is a significant performance penalty (or, battery drain)
* The configuration to be used with browser dialer cannot use custom SNI or host headers. `SNI == host == address`. Custom HTTP headers and `tlsSettings` are ignored entirely.
## Configuration
1. Prepare a usable WebSocket or SplitHTTP configuration. Be aware of the above restrictions.
2. Launch Xray with `XRAY_BROWSER_DIALER=127.0.0.1:8080`. On Windows, this can be done as `set XRAY_BROWSER_DIALER=...` and then launching the core from the console, on Linux the core can be launched as `XRAY_BROWSER_DIALER=127.0.0.1:8080 ./xray -c config.json`.
3. Open a browser that is not tunneled through the proxy, or modify the config's routing such that the Xray server's domain goes to `freedom` directly from the client. Browse to `localhost:8080`, and open the developer console with `F12` to monitor for errors.
4. For better performance and to bypass arbitrary connection limits enforced by the browser, it is recommended to enable `Mux.Cool`.
## Inner workings
- Xray listens on `http://127.0.0.1:8080`, and the browser accesses `http://127.0.0.1:8080` to load the `JS` in the webpage.
- The `JS` actively establishes a WebSocket connection to `http://127.0.0.1:8080`. Xray will use this connection to send instructions, but for now it goes into a connection pool (implemented as Go channel).
- When a connection needs to be established, Xray receives an available connection from the pool and sends the protocol name, target URL and optional early data.
- Once the `JS` successfully connects to the target, it informs Xray and continues to use this conn to bi-directionally forward data.
- After the connection to the server is closed, the connection to localhost is also closed, but the JS ensures that there is always at least one idle connection available.
## WebSocket
<Badge text="v1.4.1+" type="warning"/>
According to the browser's needs, the early data mechanism has been adjusted as follows:
@ -25,12 +44,10 @@ According to the browser's needs, the early data mechanism has been adjusted as
- The encoding used for early data for browsers is `base64.RawURLEncoding` instead of `StdEncoding`, and the server has made it compatible.
- In addition, due to [Xray-core#375](https://github.com/XTLS/Xray-core/pull/375) recommendations for `?ed=2048`, this PR also increased server `MaxHeaderBytes` by 4096. ~~(Although it seems like it would work without modification.)~~
## Configuration <Badge text="v1.4.1" type="warning"/>
## SplitHTTP
This is an exploratory process, and the configuration method used when both sides are Xray-core v1.4.1 is as follows:
<Badge text="v1.8.19+" type="warning"/>
- Prepare a usable WSS configuration, making sure to fill in the domain name for the address. If you need to specify an IP address, configure DNS or system hosts.
- If browser traffic will also pass through Xray-core, be sure to set this domain name as a direct connection, otherwise it will cause traffic looping.
- Set the environment variable to specify the address port to listen on, such as `XRAY_BROWSER_DIALER = 127.0.0.1:8080`.
- First run Xray-core, then use any browser to access the specified address port, and you can also check `Console` and Network with `F12`.
- The browser will limit the number of WebSocket connections, so it is recommended to enable `Mux.Cool`.
SplitHTTP supports QUIC, but the browser's own QUIC stack may be used as well. In Chrome this can be done through `chrome://flags`, in other browsers it may already be enabled or need a different flag.
In general, `tlsSettings` are completely ignored when Browser Dialer is used. Xray does not have any control over which HTTP version the browser selects.