Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does uTLS change the cipher suites? #461

Closed
HirbodBehnam opened this issue Mar 31, 2021 · 15 comments
Closed

Does uTLS change the cipher suites? #461

HirbodBehnam opened this issue Mar 31, 2021 · 15 comments

Comments

@HirbodBehnam
Copy link
Contributor

HirbodBehnam commented Mar 31, 2021

Hello
Thanks for the new uTLS update! But I have actually noticed that it doesn't affect the cipher suites while looking at it with wireshark.
Is this intended?
Thanks

Edit:
Here is my config file:

{
	"log": {
		"access": "none",
		"loglevel": "none"
	},
	"inbounds": [
		{
			"port": 10808,
			"listen": "127.0.0.1",
			"protocol": "socks",
			"settings": {
				"udp": true
			}
		},
		{
			"port": 10809,
			"listen": "127.0.0.1",
			"protocol": "http"
		}
	],
	"outbounds": [
		{
			"protocol": "vless",
			"settings": {
				"vnext": [
					{
						"address": "...",
						"port": 443,
						"users": [
							{
								"id": "...",
								"encryption": "none",
								"level": 0
							}
						]
					}
				]
			},
			"streamSettings": {
				"network": "tcp",
				"security": "tls",
				"tlsSettings": {
					"serverName": "...",
					"fingerprint": "chrome"
				}
			}
		}
	]
}

I also used a simple print command to make sure that the program is reaching this line and it was reaching there.

@RPRX
Copy link
Member

RPRX commented Apr 1, 2021

感谢测试,如果情况属实,则是非预期行为,但代码内对 uTLS 的调用似乎没有问题,uTLS 给出的例子如下:

https://github.com/refraction-networking/utls#migrating-from-cryptotls

或许修改一下 CopyConfig 函数试试?比如只传 ServerName

@HirbodBehnam
Copy link
Contributor Author

HirbodBehnam commented Apr 1, 2021

Hello
I did some experiments and found a way to make it work. I'm not sure why, but using Handshake function before assigning the utls config to conn, made the connection to use the fingerprint.
The only thing I did was to change the line

conn = utls.UClient(conn, tls.CopyConfig(tlsConfig), fingerprint)

To

utlsConn := utls.UClient(conn, tls.CopyConfig(tlsConfig), fingerprint)
err = utlsConn.Handshake()
if err != nil {
	return nil, err
}
conn = utlsConn

This is probably a bad idea to initiate the handshake in Dial function.
I also tested the CopyConfig you mentioned and omitted all fields except ServerName and didn't had any effect.

This is really interesting because even If I send a message (I just used conn.Write([]byte(""))) just before the Dial function exits, It will initiate the connection with chrome fingerprint.

I will investigate more to see what happens...

Edit:
If you want to check for chrome fingerprint yourself, open the wireshark, filter the packets with ssl.handshake.type == 1 && ip.host == 1.1.1.1 (where 1.1.1.1 is your server's IP) and look at the cipher suites of the TLS handshake. The first cipher must be Reserved (GREASE)

@RPRX
Copy link
Member

RPRX commented Apr 1, 2021

This is really interesting because even If I send a message (I just used conn.Write([]byte(""))) just before the Dial function exits, It will initiate the connection with chrome fingerprint.

这的确非常神奇...应该和 Xray-core 其它地方的代码有关

@HirbodBehnam
Copy link
Contributor Author

So I found something else which might help.
The utls cannot initiate the handshake because it has been completed. In other words, the code reaches this line.

@HirbodBehnam
Copy link
Contributor Author

I did one more thing. At the first line of this function, I just wrote panic() to get the stack trace. Here is the result:

goroutine 10 [running]:
github.com/refraction-networking/utls.(*clientHandshakeStateTLS13).handshake(0xc000027a88, 0xc000266000, 0x0)
        github.com/refraction-networking/utls@v0.0.0-20201210053706-2179f286686b/handshake_client_tls13.go:43 +0x45
github.com/refraction-networking/utls.(*Conn).clientHandshake(0xc0002ea000, 0x0, 0x0)
        github.com/refraction-networking/utls@v0.0.0-20201210053706-2179f286686b/handshake_client.go:199 +0x4d3
github.com/refraction-networking/utls.(*Conn).Handshake(0xc0002ea000, 0x0, 0x0)
        github.com/refraction-networking/utls@v0.0.0-20201210053706-2179f286686b/conn.go:1362 +0xd9
github.com/refraction-networking/utls.(*Conn).Read(0xc0002ea000, 0xc00001c000, 0x1, 0x2000, 0x0, 0x0, 0x0)
        github.com/refraction-networking/utls@v0.0.0-20201210053706-2179f286686b/conn.go:1242 +0x5a
io.ReadAtLeast(0x251dfdd23b0, 0xc0002a10e0, 0xc00001c000, 0x1, 0x2000, 0x1, 0x0, 0x0, 0x0)
        io/io.go:328 +0x8e
io.ReadFull(...)
        io/io.go:347
github.com/xtls/xray-core/common/buf.(*Buffer).ReadFullFrom(0xc000027d88, 0x251dfdd23b0, 0xc0002a10e0, 0xc000000001, 0x251dfdd23b0, 0xa69dae, 0x0)
        github.com/xtls/xray-core/common/buf/buffer.go:226 +0xab
github.com/xtls/xray-core/proxy/vless/encoding.DecodeResponseHeader(0x251dfdd23b0, 0xc0002a10e0, 0xc0002d66f0, 0x0, 0x0, 0x0)
        github.com/xtls/xray-core/proxy/vless/encoding/encoding.go:163 +0x145
github.com/xtls/xray-core/proxy/vless/outbound.(*Handler).Process.func3(0x0, 0x0)
        github.com/xtls/xray-core/proxy/vless/outbound/outbound.go:224 +0x165
github.com/xtls/xray-core/common/task.OnSuccess.func1(0x0, 0x0)
        github.com/xtls/xray-core/common/task/task.go:12 +0x36
github.com/xtls/xray-core/common/task.Run.func1(0xc000208060, 0xc0002f2360, 0xc0001de1c8)
        github.com/xtls/xray-core/common/task/task.go:28 +0x32
created by github.com/xtls/xray-core/common/task.Run
        github.com/xtls/xray-core/common/task/task.go:27 +0x15c

And here is what happens:
The Read function is NOT a part of the UConn struct! It is a part of the Conn struct! And when it is called, it doesn't call the utls Handshake method instead it calls the simple conn Handshake which doesn't use the fingerprint of browsers!

I will check if there is a good way to force the fingerprints before calling the Read method. (Probably a good thing to place in Dial function.

@RPRX
Copy link
Member

RPRX commented Apr 1, 2021

@HirbodBehnam

ok,所以这里的问题是 uTLS 认为调用方会先调用 Write,而如果调用方先调用了 Read 则会进行普通 TLS 握手

我认为这属于 uTLS 的 bug,或许在他们进行修复之前,手动调用 Handshake 比较合适

@HirbodBehnam
Copy link
Contributor Author

So there are some ways I can currently think of to fix this bug:

  1. Use the Handshake method. It will simply do the tls handshake. In my opinion, the Dial function is not a good place to call the handshake method. (Might be a good place too, I'm familiar with xray code)
  2. Fork the utls and implement the read method for UConn struct. Probably just copy and pasting the Read method of Conn for UConn and some small changes to make it like Write method is sufficient. Because it will call the Handshake function for UConn not the Conn.
  3. Maybe another function exists to just build and apply the ciphers and key exchange algorithms? I shall have a look at the documentation.

@HirbodBehnam
Copy link
Contributor Author

@HirbodBehnam

ok,所以这里的问题是 uTLS 认为调用方会先调用 Write,而如果调用方先调用了 Read 则会进行普通 TLS 握手

我认为这属于 uTLS 的 bug,或许在他们进行修复之前,手动调用 Handshake 比较合适

Exactly I think this is true!

@RPRX
Copy link
Member

RPRX commented Apr 1, 2021

@HirbodBehnam 感谢你的工作,我会先对代码进行适当的修改,同时你可以向 uTLS 反馈这个 bug

另外请帮忙测试一下 WSS Browser Dialer 在安卓上的表现,以及代理软件内置 WebView 的可行性

@HirbodBehnam
Copy link
Contributor Author

@RPRX Yes I did open a new issue here

Yes, I will surely test the new WSS Browser Dialer soon and report any problems which I encounter!

Thanks for the great project and your effort!

P.S: I will keep this issue open until it's fixed...

RPRX added a commit that referenced this issue Apr 1, 2021
@RPRX
Copy link
Member

RPRX commented Apr 1, 2021

修复了此问题、优化了些代码,请测试 4bf8b6d https://github.com/XTLS/Xray-core/actions/runs/707998613

@RPRX
Copy link
Member

RPRX commented Apr 1, 2021

P.S: 怪不得 #212 调用了 Handshake()

@ghost
Copy link

ghost commented Apr 1, 2021

Closed by 4bf8b6d.

@ghost ghost closed this as completed Apr 1, 2021
@HirbodBehnam
Copy link
Contributor Author

Thanks for the fast implementation! I can confirm that it is now working as intended!

@RPRX
Copy link
Member

RPRX commented Apr 1, 2021

@HirbodBehnam https://github.com/XTLS/Xray-core/releases/tag/v1.4.2

mwhorse46 added a commit to mwhorse46/Xray-core that referenced this issue Feb 19, 2023
rampagekiller0725 added a commit to rampagekiller0725/wox that referenced this issue Jun 29, 2023
Autumn216 added a commit to Autumn216/wox that referenced this issue Oct 31, 2023
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants