XTLS / Xray-core

Xray, Penetrates Everything. Also the best v2ray-core, with XTLS support. Fully compatible configuration.
https://t.me/projectXray
Mozilla Public License 2.0
25.61k stars 3.96k forks source link

How to block Bittorrent traffic via nDPI module (IPtables) #2300

Closed houmie closed 7 months ago

houmie commented 1 year ago

Most VPS service providers do not allow Bittorrent downloading due copyright issues. However, some people are not aware of this. And no matter how much this is explained there is always somebody using torrents to download movies. The best way is to stop the torrent traffic within xray-server altogether. But this is not easy.

In theory the protocol could be blocked via this config below.

Inbounds:

"sniffing":{
            "enabled":true,
            "destOverride":[
               "http",
               "tls"
            ]
         }
"routing":{
      "domainStrategy":"IPIfNonMatch",
      "rules":[
         {
            "type":"field",
            "outboundTag":"block",
            "protocol":[
              "bittorrent"
            ]
         }
       ]
}

However this doesn't work reliably with VLESS-VISION-TCP-REALITY.

Looking at the /var/log/xray/access.log I can see some packages are blocked and others go through. It can't block all of the connections, it will only slow this down.

2023/07/07 16:39:13 140.228.xx:32368 accepted tcp:51.159.4.xxx:55463 [block]
2023/07/07 16:39:13 140.228.xx:32012 accepted tcp:96.244.189.xxx:58946 [direct]
2023/07/07 16:39:18 140.228.xx:29768 accepted tcp:ipv6.torrent.ubuntu.com:443 [block]
2023/07/07 16:39:18 140.228.xx:29378 accepted tcp:torrent.ubuntu.com:443 [block]

I'm using Bittorrent app on Android (from Playstore): Screenshot_20230708-090420

As you can see there is no way to stop the peer-to-peer traffic.

I know from experience, that this nDPI project works with Wireguard.

But because V2Ray/Xray operates at the application layer of the network stack (as opposed to the network layer for Wireguard/OpenVPN), it doesn't need to alter IP packet headers, so there's no need for NAT or masquerading.

The core challenge here is that the nDPI module is designed to operate at the network layer, inspecting packets directly. While Xray operates at the application layer, it doesn't mean nDPI or any L7 filter couldn't analyze its traffic. Xray, as a proxy tool, encrypts the traffic between the client and the server. This makes it challenging for a DPI tool like nDPI to determine the application-level protocol, because it cannot see into the encrypted data.

Unless there was a way to hook that into the unencrypted traffic within Xray.

So what can we really do to prevent Bittorrent properly?

mmmray commented 1 year ago

torrent filtering does not work reliably, but I have also found that once your config is public, users will do all kinds of stuff that will upset your vps provider.

I have resorted to routing all traffic via wireguard to mullvad where none of this stuff matters. this removes the piracy problem and having a separate exit IP also means that you don't have to block domestic IPs because requesting them does not reveal your inbound proxy IP.

it does however mean a lot of cloudflare captchas because mullvads IPs are very dirty

houmie commented 1 year ago

Doesn't that mean you would be using Wireguard instead of Xray though? Or are you combining an Xray protocol with Wireguard?

timi-owo commented 1 year ago

Blocking tracker servers would be better.

houmie commented 1 year ago

I have tried blocking tracker servers before, but it's not a reliable solution.
They can disable the VPN, open the tracker site, download the magnet file and open it. Then activating VPN again and start downloading. It's very easy.

mmmray commented 1 year ago

@houmie

Doesn't that mean you would be using Wireguard instead of Xray though? Or are you combining an Xray protocol with Wireguard?

I use xray, but not with the Freedom protocol, my outbound protocol is wireguard. clients still connect to xray

houmie commented 1 year ago

@mmmray

I use xray, but not with the Freedom protocol, my outbound protocol is wireguard. clients still connect to xray

That's amazing. I didn't know that is even possible. Does it mean the user can still use VLESS-VISION-TCP-REALITY to overcome the firewall and connect to your VPS. Then the outgoing protocol from your server points to your local Wireguard that diverts the traffic to an external service (like Mulvad). That will make the connection a bit slower though, right?

And do you have any example how to set this up? This is the first time I hear about this.

mmmray commented 1 year ago

@houmie

That's amazing. I didn't know that is even possible. Does it mean the user can still use VLESS-VISION-TCP-REALITY to overcome the firewall and connect to your VPS. Then the outgoing protocol from your server points to your local Wireguard that diverts the traffic to an external service (like Mulvad). That will make the connection a bit slower though, right?

your description of traffic flow is correct. client configs stay entirely the same, there is no restriction on inbound protocols that I have seen. the maximal potential impact is that they can't access certain websites that might have mullvad blocked, and performance

latency/ping is slightly worse, but in the end a lot of VPN providers give you a lot of server choices, and the connection between two western european servers is not that bad.

throughput/bandwidth is usually bottlenecked by GFW. Honestly, latency is also already ruined by GFW. I am not talking about the chinese GFW though.

  1. register for mullvad, create a new client there

  2. download their wireguard config for just one server, the file itself is for wireguard client but it's just a text file with the values you need. the file looks like this:

    [Interface]
    # Device: Grown Clam
    PrivateKey = PRIVATEKEY
    Address = ADDRESS/32,fc00:bbbb:bbbb:bb01::2:3891/128
    DNS =...
    
    [Peer]
    PublicKey = PUBLICKEY
    AllowedIPs = 0.0.0.0/0,::0/0
    Endpoint = ENDPOINT
  3. replace "outbounds": [ {"protocol": "freedom", ...}, ..., ] with

    "outbounds": [
    {
        "protocol": "wireguard",
        "settings": {
          "secretKey": "PRIVATEKEY",
          "address": [
            "ADDRESS"
          ],
          "peers": [
            {
              "publicKey": "PUBLICKEY",
              "allowedIPs": [
                "0.0.0.0/0",
                "::/0"
              ],
              "endpoint": "ENDPOINT"
            }
          ]
        }
      },
    
      # any remaining not-freedom outbounds you might have
    ]

I believe you can have multiple "outbounds" to use multiple mullvad servers, but I haven't tried, and I don't understand what the ramifications are if your IP keeps changing during usage. you can use xray to do some custom routing, it's the same mechanism with which you send certain IPs into "blackhole" outbound.

Keep in mind that the CPU usage increases a lot. I can't remember how much, probably less than doubled CPU usage. From what I remember, xray's wireguard support is still a lot more efficient than connecting via SOCKS to a separate wireguard client.

houmie commented 1 year ago

Thank you for sharing this. That's very kind.

donnyxray commented 1 year ago

Alternative solution: use xray-core torrent filter to detect torrent users, not to clean up traffic. Then use a simple script that tails the log file to block the user completely for a number of hours and send them an automated notice.

I've been doing it this way for years and it's very effective at avoiding DMCA notices. Most users respond very reasonably as they understand it protects a service they enjoy. Typically they just make a mistake and have no ill intent.

houmie commented 1 year ago

@donnyxray That's a great alternative solution. Would you mind to elaborate a bit more on how you detect if the user is using torrent via xray-core torrent filter?

{
        "type": "field",
        "outboundTag": "block",
        "protocol": [
          "bittorrent"
    ]
},

This is the one thing I know that tries to identify bittorrent to block it. But that works very poorly. Torrents can work even without a seeder and find other peers to download from via PEX and DHT. So it is almost impossible to block it, but as you say it should be possible to detect it.

So how is your solution? Could you give a sample and elaborate a bit more in detail, please?

Thank you

donnyxray commented 1 year ago

A simplified example would be:

tail -f /var/log/xray/access.log | grep --line-buffered '[block]' | awk '{print $3}' | cut -d':' -f1 | xargs -I {} sudo iptables -A INPUT -s {} -j DROP

This way it's not necessary to identify all torrent traffic. You just need to detect 1 single connection to block the user who makes a mistake. In my experience this is 100% effective in avoiding DMCA notices.

Regarding PEX, DHT, etc: I'm sure if someone nefariously wanted to shut down your VPS they could succeed. But this is an unlikely scenario. In my experience it's just people who make a mistake and are easily detected.

kastov commented 1 year ago

A simplified example would be:

tail -f /var/log/xray/access.log | grep --line-buffered '[block]' | awk '{print $3}' | cut -d':' -f1 | xargs -I {} sudo iptables -A INPUT -s {} -j DROP

This way it's not necessary to identify all torrent traffic. You just need to detect 1 single connection to block the user who makes a mistake. In my experience this is 100% effective in avoiding DMCA notices.

Regarding PEX, DHT, etc: I'm sure if someone nefariously wanted to shut down your VPS they could succeed. But this is an unlikely scenario. In my experience it's just people who make a mistake and are easily detected.

Great solution, but seems like it is not work with Trojan+WS+TLS, but works with TCP.

houmie commented 3 weeks ago

Hello @donnyxray

Sorry for replying so late. I just tried your approach to identify torrent usage, but there's an issue: nothing gets tagged as [block] because all blocked traffic is sent to the blackhole. Let me explain:

In Xray, I have the following snippet to block Bittorrent:

{
    "type": "field",
    "outboundTag": "block",
    "protocol": [
        "bittorrent"
    ]
},

Because they are tagged as [block], they will be caught by the blackhole and simply discarded. They never appear in the access.log in the first place.

{
    "protocol": "blackhole",
    "tag": "block",
    "settings": {}
}

I tested this on my Mac. I connected to my Xray VPS server and started downloading Ubuntu.iso as a torrent.

At first, nothing goes through because of the block, which is great. But if I stop the connection and let it do the handshake and start downloading a little bit, then reconnect back to the Xray VPS, the traffic will no longer be blocked. Xray can't detect this because the handshake occurred before the user reconnected.

All I see in my access.log is this:

2024/10/21 12:45:41 from 188.214.x.xxx:64305 accepted tcp:82.49.189.xxx:56665 [direct] email: 0b8c6154-856d-4b32-8932-8e9f10d14000@VLESS_TCP_REALITY_B.io
2024/10/21 12:45:41 from 188.214.x.xxx:65416 accepted tcp:76.155.150.xxx:11903 [direct] email: 0b8c6154-856d-4b32-8932-8e9f10d14000@VLESS_TCP_REALITY_B.io
2024/10/21 12:45:42 from 188.214.x.xxx:63070 accepted tcp:121.119.115.xxx:14664 [direct] email: 0b8c6154-856d-4b32-8932-8e9f10d14000@VLESS_TCP_REALITY_B.io

These are the torrent traffic entries, but all are tagged as [direct].

I understand that catching just one entry should be enough to block the traffic and prevent DMCA notices. However, I'm catching none because there are no entries with [block]. If there were, they would be filtered out in the blackhole anyway.

I'm not sure how you achieved this. Do you mind elaborating, please? I think there must be another part to your configuration that I'm missing.

donnyxray commented 3 weeks ago

Please check your own opening post. It has log lines showing [block].

I don't know what you changed to make these log lines disappear. Your original configuration will do the trick.