Xray-core
Xray-core copied to clipboard
UDP noise
sometimes internet providers block curtain udp based protocols(quic,wireguard) but udp itself is not blocked or throttled
using this strategy we can bypass almost all udp based protocol restrictions
This is how it works:
we want to use wireguard but our provider blockes it,The way they mostly do it is they almost always only inspect the first packet in each socket and if they see it is wireguard they will just drop everything on that socket
As I sayed they will inspect the socket only once and that's it, and with some noise we can fool them
What is noise:it is basicly a random nonesense packet that we send before wireguard or quic handshake,the server will ignore that packet like it was never sent but the gfw will inspect it and once it did not find anything suspicious they will let the connection go smoothly,
I will atach two screen shots of wireshark showing this behavior(this ISP blockes quic)
this PR is draft and not ready at all,I just wanted to discuss this with maintainer to see if you are interested in this feature I will attach a sample config for people to test this(it is basicly a splithttp h3 with dialerProxy to freedom) vless-splithttp-quic-dialer-proxy -clean.json
right now there is no option for enabling or disabling this feature as I did not want to spend a lot of time changing protobuf and json parser before discussing it with maintainers this strategy I believe has a lot of pottential: bypassing wireguard and quic protocol blocking bypassing sni based filtering or whitelisting on quic(this does not happen right now but if or when they start doing it,this can easily bypass them) right now the type of noise is a random byte generated by crypto/rand and it sends the noise in the first write to socket and if we want we could have other types of noise too(a video call packet,quic handshake packet with whitelisted sni,Dtls or whatever)
This idea was discussed privately with OP for a while. To clarify, the added noise packets work for some protocols and disrupt others, but for QUIC/H3 it allegedly works with CDN (although I have not tested it myself)
I think it would be too much maintenance effort to add specialized support for "fake clienthello", "fake wireguard", "fake voip", etc. Just let the user specify a bytestring directly, and that bytestring will be written as-is. They can write their own clienthello, or copy from some template.
Anyway, I think the idea is good.
This idea was discussed privately with OP for a while. To clarify, the added noise packets work for some protocols and disrupt others, but for QUIC/H3 it allegedly works with CDN (although I have not tested it myself)
I think it would be too much maintenance effort to add specialized support for "fake clienthello", "fake wireguard", "fake voip", etc. Just let the user specify a bytestring directly, and that bytestring will be written as-is. They can write their own clienthello, or copy from some template.
Anyway, I think the idea is good.
I don't think this would disrupt anything(unless the transport has issues with dialer proxy,if u are talking about the line where I check for port 53 it wasn't because it disrputs dns,without that if condition the udp dns was fine I just added just to be safe),I tried with vless-splithttp quic and wireguard,both worked fine,About the packet type I think it is best to have two modes:1-the one u said with a user input string 2-a random generated byte that user would choose the min and max length for that byte
~~Thanks, but we currently prefer not to merge such 'tricks'~~
~~see https://github.com/XTLS/Xray-core/pull/3677#issuecomment-2285951455~~
Looks like rprx would like to merge, see what can we do
Thanks, but we currently prefer not to merge such 'tricks'
see #3677 (comment)
I undrestand why u say this,u might be right the second u merge it people will use it and providers will just throttle udp for cloudflare,but it is not just about using it with cloudflare ,imagine I want to use a free wireguard service (I am not talking about warp,this one is already throttled heavily but there are others too,don't want to name them here) there is no way I can use them normaly but with this trick it works,basicly more people will have access to free proxy services,this is not a full solution but for a lot of times it could be usefull,and lastly they might throttle cloudflare but what if i want to use this with another cdn?amazon(this one almost never gets QOSed atleast where I live and I think it supports quic too) and I am not saying everyone should go and use amazon I am saying "if" anyone wants to use it this can help , as I mentioned it is not a full solution ,Best of luck to all the developers of this project other thing is most firewalls have limited resources and usually they do very little inspection when it comes to udp and this trick really takes advantage from that
Any how it is useful may be we will merge it privately.
My take is we can do if change is clean and organized in one place. This method remind me of https://gfw.report/publications/usenixsecurity23/en/#8-1-customizable-payload-prefixes and https://github.com/v2fly/v2ray-core/pull/1552
It's a good option for SplitHTTP for CDN, but not for QUIC, as they already have Obfuscation options
Just let the user specify a bytestring directly, and that bytestring will be written as-is. They can write their own clienthello, or copy from some template.
Agree, but base64url is better than bytestring and maybe a list of timing options appended to the payload
This method remind me of https://gfw.report/publications/usenixsecurity23/en/#8-1-customizable-payload-prefixes and v2fly/v2ray-core#1552
So it is possible to do the same for non-HTTP/non-TLS TCP connections like VMESS+TCP ?
seam to be working usage:
{
"protocol": "freedom",
"settings": {
"noise":{
"packet":"rand:5-10", //str:higfw
"delay":"5-10"
}
},
"tag": "direct"
},
I wrote two types of packet: rand:min-max length str:whatttttever I added option for delay too,by defualt it is 0 but if anyone wants to add a delay before sending the real data it is here And the tests should probably pass now
My take is we can do if change is clean and organized in one place. This method remind me of https://gfw.report/publications/usenixsecurity23/en/#8-1-customizable-payload-prefixes and v2fly/v2ray-core#1552
赞同
You can make it more advanced, to make firewalls unable to block it easily you can add multiple payload support (for example: send static fake data and then 2 random data, with or without delay between them, and then the real data)
我认为现在的代码应该精简一些 最开始那一版就可以 加上json设置delay和随机字节长度就行了 这东西非常非常容易被滤掉 搞得再高精尖对面patch一下有问题的udp conn track就毙掉了 不用搞得太复杂 还搞个浮动
the config parsing for fragment is really extreme levels of copy-pasting, and it seems that in order to be consistent with it, delay should be uint. maybe it should be refactored in a later PR to use something like https://github.com/XTLS/Xray-core/blob/c0c23fdfeb9ea813482a110a32f5203371499512/infra/conf/common.go#L247-L249
Yes, the config parsing of fragment is very very confusing
@mmmray I will fix the issues u said hopefully in a hour or two I added that delay so if firewall would try to gather more data from the connection it would make it harder,I think it could be useful,right now it does not make much diffrence so if u say so I could remove it(but I suggest we keep it)
@yuhan6665 Is it possible to do similar thing to full random TCP connections like VMESS+TCP ? for example send a mssql header and then send the real data and start communication to the proxy server, firewall must consider the connection as a regular mssql connection or append a fake header to client's first request packet, and make the server ignore it
it is very unlikely to work for any TCP-based protocol. let's try to focus on getting this PR merged and discuss other ideas elsewhere...
Looks ok to me. Thanks for the good collaboration
If UseAlternativeSystemDialer is used this will cause issue. e.g. the protected dialer of v2rayNG doesn't return a *PacketConnWrapper(in fact it is *net.UDPConn), so assertion will fail and PacketWriter and PacketReader of freedom will not be used. How come almost nobody found "full cone nat" is broken for freedom in v2rayNG in the past years? Xray and/or AndroidLibXrayLite need fixes for this.
How come almost nobody found "full cone nat" is broken for freedom in v2rayNG in the past years?
Adding a *net.UDPconn assertion in case of *Packetconnwrapper assertion failure should fix this,right?(not sure if this is the best way to fix) Is there a specific reason why v2rayng returns net.udpconn instead on packetconnwrapper?
v2rayNG use this for VpnService protection. Maybe Xray need to fix its freedom NewPacketReader and NewPacketWriter not to strongly rely on *PacketConnWrapper first.
As the system dialer is designed to be alterable, and Dial returns a net.Conn, it is not guaranteed that a net.Conn can be casted to *PacketConnWrapper or *net.UDPConn. So you may need a universal net.Conn writer as the last resort.
i think a developer did it in a xray fork for iranian users
https://github.com/GFW-knocker/Xray-core
this is the project
Freedom PacketWriter has been updated. I don't know about your firewall policy for single-socket multi-destination but you might want to update your code too. (e.g. one writer using net.PacketConn WriteTo, and another using net.Conn Write if not a net.PacketConn)
Thanks, fair enough. I think this commit should fix it, please check it... although this noise generator is mostly for a freedom dialerProxy on the tunnel's connection, and so I think the cone-ness of that outer protocol doesn't matter that much :thinking:
Merged. Thanks all!
~~又要在 release notes 中改 commit title 了~~
我简单看了下配置,为什么这个不叫 udpnoise,~~好吧 fragment 也没叫 tcpfragment,那没事了~~
感觉这里确实需要 base64 来支持非可打印字符,以及需要数组以支持连发多个 noise 包,“不能出现冒号”的限制应当去掉
@Fangliding 文档把 Freedom 改为“Freedom(fragment、noise)”,~~还有顶部配置示例中 "noise" 咋被绿了~~
以及需要数组以支持连发多个 noise 包
大概需要 noise 本身变成数组 noises
感觉这里确实需要 base64 来支持非可打印字符,以及需要数组以支持连发多个 noise 包,“不能出现冒号”的限制应当去掉
Base64确实可以 不能用冒号是因为代码里用 split : 来分割 用冒号就割成几个了 当然如果换base64或者SplitN就可以解决这个问题了
至于发几个个人觉得就没啥必要了 等有墙开始开始解析第二个数据包但是放过第三个再说
@Fangliding 文档把 Freedom 改为“Freedom(fragment、noise)”,~还有顶部配置示例中 "noise" 咋被绿了~
Done, 变绿是因为不小心打出了个中文冒号