qbittorrent / qBittorrent

qBittorrent BitTorrent client
https://www.qbittorrent.org
Other
28.56k stars 4k forks source link

Fake Peers on port 80 through Peer Exchange #12408

Closed VolatileCable closed 4 years ago

VolatileCable commented 4 years ago

qB!4.2.3 Win10 x64

I noticed this on the archlinux torrent. After a while your peer list will be filled with these 'fake' peers supposedly listening on port 80 over standard BT protocol. At first I thought this might be some amplification attack utilizing this popular torrent, but on further inspection, by enabling host name resolution, you can tell that most of these peers are mirror/web servers. I can only imagine some faulty client somehow pollutes the PEX with these servers. The archlinux torrent itself doesnt have web seeds either. These peers are all stuck at 0% and payload transfer happens. But they do count towards the active peers in the overview list.

It would be nice if they would be recognized as non-BT hosts and maybe some basic filtering for PEX and ports 80 and 443 would be implemented.

qbittorrent fake peers

magnet:?xt=urn:btih:1027de87dc168253781f83b183ece4dffa402f40&dn=archlinux-2020.04.01-x86_64.iso&tr=udp://tracker.archlinux.org:6969&tr=http://tracker.archlinux.org:6969/announce

FranciscoPombal commented 4 years ago

It would be nice if they would be recognized as non-BT hosts and maybe some basic filtering for PEX and ports 80 and 443 would be implemented.

Filtering like this could be dangerous, it is possible that you would block legit peers that are using port 80 for BitTorrent (though I realize that is unlikely). It seems qBittorrent/libttorrent actually think they have successfully established a BT connection with those peers. Maybe that detection is faulty, because I tested a few, and they serve HTTP. Perhaps libtorrent is just checking if a TCP connection gets established.

@arvidn Is it possible that someone added those servers as webseeds, and then libtorrent shared them as regular peers?

Kolcha commented 4 years ago

I saw even more strange situation: a lot of connections from port 11 or even 1, but in most cases such peers had ancient libtorrent version (0.16.x) as client string... and these peers also reported some progress or even upload speed, but these values remain constant during time and was the same for all torrents (very often one such peer requested a lot of torrents) for the same peer, so that was fake... great fake...

to drop such connections, I just patched qBittorrent to set no_connect_privileged_ports libtorrent option. now I don't observe such strange connections. recently I also setup iptables to drop any incoming connections from low port values (< 2048)

arvidn commented 4 years ago

I would expect libtorrent to establish a TCP connection to these servers and send a bittorrent handshake. Then eventually time-out, as (presumably) they won't send anything back. I would expect the timeout to be 60 seconds or so, maybe less.

Do the peers stay connected for longer than that?

VolatileCable commented 4 years ago

@arvidn

Yes, definitely longer. I'm not quite sure how but eventually they do disappear though.

I just checked it with Wireshark and there seems to be some keep-alive every 60s. My systems sends a TCP with PSH, ACK and four 0x00 bytes as payload to which these servers reply with ACK.

@Kolcha

Yes, filtering privileged ports seems like a good idea regardless of this connection issue here. There aren't many legitimate use cases for it and just more danger for abuse. The connections were enabled here in qBittorrent after libtorrent started blocking them by default back in 2014:

https://qbforums.shiki.hu/viewtopic.php?t=2951 https://libtorrent-discuss.narkive.com/9aBduh66/is-no-connect-privileged-ports-really-that-useful https://github.com/qbittorrent/qBittorrent/commit/1110617896ed21b415e9cb09f349c21601b7d146

FranciscoPombal commented 4 years ago

IMO we should probably block privileged ports by default, maybe leave it configurable as an advanced setting.

arvidn commented 4 years ago

libtorrent used to to this by default (iirc), and my recollection is that there are a bunch of people that run on port 80 and 443, perhaps they are "connectivity challenged"

Kolcha commented 4 years ago

there are a bunch of people that run on port 80 and 443, perhaps they are "connectivity challenged"

it makes sense, VPN provider I use also has options to choose port 80 or 443 as port for VPN connections due to user's ISP restrictions...

VolatileCable commented 4 years ago

I would imagine it's mostly corporate and school networks, where this is the case and where you shouldnt and most likely arent allowed to torrent anyway. It's not like bittorrent is a life-critical service for whistleblowers who needs to steganographically blend in with https or something.

But anyway, this is really a seperate topic. The underlying issue is that something keeps these connections alive and they aren't detected as not-bittorrent-peer. I imagine this a libtorrent bug?

FranciscoPombal commented 4 years ago

I would imagine it's mostly corporate and school networks, where this is the case and where you shouldnt and most likely arent allowed to torrent anyway. It's not like bittorrent is a life-critical service for whistleblowers who needs to steganographically blend in with https or something.

Still I think we should do our best to avoid such limitations. We can't just arbitrarily say "well, you can't use BitTorrent because you're at work/school", it is supposed to be neutral. Besides there are legitimate reasons to use ports 80 and 443 outside of work/school.

But anyway, this is really a seperate topic. The underlying issue is that something keeps these connections alive and they aren't detected as not-bittorrent-peer. I imagine this a libtorrent bug?

Yep, this is my suspicion as well.

levicki commented 4 years ago

Still I think we should do our best to avoid such limitations. We can't just arbitrarily say "well, you can't use BitTorrent because you're at work/school", it is supposed to be neutral. Besides there are legitimate reasons to use ports 80 and 443 outside of work/school.

On one hand, I do agree that you should not be the judge whether it is OK to use torrents at work/school. My personal opinion is that it isn't OK, but IT admins already have tools to deal with it.

On the other hand, I believe that there are no legitimate reasons to allow using ports lower than 1024 for peer-to-peer connections.

FranciscoPombal commented 4 years ago

On one hand, I do agree that you should not be the judge whether it is OK to use torrents at work/school. My personal opinion is that it isn't OK, but IT admins already have tools to deal with it.

Work/school is just an example. There's also the case of restrictive airport networks, for example, where a moral judgement argument of "you shouldn't be torrenting there" does not apply so strongly. The point is that BitTorrent is just a network protocol, and thus should be neutral w.r.t. those moral judgments/peculiarities of human activity.

On the other hand, I believe that there are no legitimate reasons to allow using ports lower than 1024 for peer-to-peer connections.

By default. There should still be the option to use them. Again, because you can't possibly predict that there are no legitimate instances where you would really need to use such ports. IMO BitTorrent must allow such freedom. Discouraging users from doing that is ok though.

levicki commented 4 years ago

@FranciscoPombal I think that allowing use of privileged ports (<1024) for p2p is a bad idea (I'd even recommend only allowing ephemeral ports by default). I am OK with "discouraging" if that means ports <1024 are disabled by default though.

arvidn commented 4 years ago

Not allowing ports <1024, does that mean

  1. Not making outgoing connections to such ports?
  2. Not accepting incoming connections from such source ports?

Or both?

I think one pragmatic point is that some anti-malware/anti-virus software really doesn’t like processes making connections to destination port 25 (SMTP)

arvidn commented 4 years ago

I would be interested in hearing some rationale for blocking ports (some more than “it seems reasonable”)

FranciscoPombal commented 4 years ago

@FranciscoPombal I think that allowing use of privileged ports (<1024) for p2p is a bad idea (I'd even recommend only allowing ephemeral ports by default). I am OK with "discouraging" if that means ports <1024 are disabled by default though.

We are on the same page then.

@arvidn

Not allowing ports <1024, does that mean

1. Not making _outgoing_ connections to such ports?

2. Not accepting _incoming_ connections from such source ports?

Or both?

Both as well as binding to them, but then again I don't mean flat-out disallowing, I mean having that disabled by default, behind a setting called "Allow/disallow connections to/from privileged ports".

I think one pragmatic point is that some anti-malware/anti-virus software really doesn’t like processes making connections to destination port 25 (SMTP)

Good example.

VolatileCable commented 4 years ago

I would be interested in hearing some rationale for blocking ports (some more than “it seems reasonable”)

Mostly against amplifications attacks. Also I wouldnt be surprised if there are crappy oem routers with eg. wan-exposed upnp or similar that you can crash by connecting or at least DOS without much effort.

arvidn commented 4 years ago

could someone experiencing this test this patch? https://github.com/arvidn/libtorrent/pull/4550

arvidn commented 4 years ago

I landed that patch. It will be part of libtorrent .1.2.6

VolatileCable commented 4 years ago

Sorry, I just don't know how to build qbittorrent or libtorrent and how it integrates into it. If someone could provide me a build, I could test the patch.

FranciscoPombal commented 4 years ago

@VolatileCable you can test with this build: https://github.com/qbittorrent/qBittorrent/issues/11735#issuecomment-617230156

VolatileCable commented 4 years ago

I just tested it for ~2h with the mentioned archlinux torrent and it's still a problem. It's slightly better than before, but they still take up a sizeable amount of the peer slots. They do seem to disconnect after a minute or two now. But shortly afterwards libtorrent just seems to reconnect to them again, possibly because it gets them through PEX again.

I guess you would need some intricate system where you automatically blacklist them for this to really get fixed or blacklist the ports.

NotTsunami commented 4 years ago

Wonder if it's worth just adding a setting withing qBit for no_connect_privileged_ports

NotTsunami commented 4 years ago

https://github.com/qbittorrent/qBittorrent/pull/12577

arvidn commented 4 years ago

They do seem to disconnect after a minute or two now. But shortly afterwards libtorrent just seems to reconnect to them again, possibly because it gets them through PEX again.

That is expected behavior, assuming there aren't any other peers. Peers are tried 3 times (by default) and then never again. there are some exceptions where the fail counter can be decremented to try the peer again. But as long as there are no other peers to try, these peers being retried immediately is expected.

VolatileCable commented 4 years ago

But as long as there are no other peers to try, these peers being retried immediately is expected.

The torrent has many thousands of potential peers listed though. How can this be true?

FranciscoPombal commented 4 years ago

Since the patch seems to work as intended, after reading through this once again, I have changed my mind about whether blocking connections to privileged ports should be the default.

In fact, I don't think this should be a configurable settings at all unless someone can prove the following is a big deal affecting many users (I don't like the idea of making changes in qBittorrent just to appease anti-virus software, unless it is really needed):

I think one pragmatic point is that some anti-malware/anti-virus software really doesn’t like processes making connections to destination port 25 (SMTP)

arvidn commented 4 years ago

The torrent has many thousands of potential peers listed though. How can this be true?

To find out, one would have to dig a bit deeper. For instance, who is saying it has thousands of peers? if it's the tracker, maybe the client hasn't learned about them. (private torrents disable all means of learning about new peers other than through the tracker, so that could be an explanation).

If libtorrent is indicating that its peer list has thousands of peers in it, then this behavior would be unexpected indeed. I'm not sure if or how qbt exposes that number.

arvidn commented 4 years ago

In fact, I don't think this should be a configurable settings at all unless someone can prove the following is a big deal affecting many users (I don't like the idea of making changes in qBittorrent just to appease anti-virus software, unless it is really needed):

The reason I can think of to make it configurable, is that some people may like their anti-virus/anti-malware software. And for them this could be quite irritating.

FranciscoPombal commented 4 years ago

@arvidn

The reason I can think of to make it configurable, is that some people may like their anti-virus/anti-malware software. And for them this could be quite irritating.

Yes, but do you happen to know how common this is, i.e. that anti-virus complains about qBittorrent specifically because of the port numbers of the connections it makes? Personally I have not seen any anti-virus -related issue that mentions this. It could be that some anti-virus -related issues are ultimately caused by this, but so far there has been no instance where that could be provable.

arvidn commented 4 years ago

Yes, but do you happen to know how common this is

I have no idea. I just remember this was discussed in the uTorrent forums about 10 years ago

levicki commented 4 years ago

I fail to see the rationale for retrying a peer once you determine it does not respond with a standard handshake.

If the response is HTTP 400 Bad request or something like that (or if it is just not a proper peer response) are you really expecting this to change if you keep retrying?

arvidn commented 4 years ago

@levicki A bittorrent handshake message does not look like an HTTP request. I suspect the server is just hanging around waiting for "\r\n\r\n" or something (which it will never see). So the stall is most likely without the server every sending any payload over the connection.

The rationale for trying peers again is that it's not unheard of that peers fail to accept connections for various reasons and then succeed at a later time. It could be that they have a full peer list or are overloaded in some other way, or have temporary connectivity issues. The default of trying peers 3 times can be changed to 1, but I doubt it will do you any good.

The important part, in my mind, is that a peer that has never been tried is tried before one that has failed once is tried again. I'm pretty confident this is the case currently.

levicki commented 4 years ago

Why not just issue GET / HTTP/1.1 (or even just \r\n\r\n to peers connected on ports 80 and 443 which don't respond in a timely manner to make sure you are not talking to a webserver instead, and then mark them as bad accordingly in the session cache or wherever this information on peers is kept?

arvidn commented 4 years ago

what other protocols do you think should get that treatment? FTP, SMTP, telnet, SSH, SSL.

It's not clear to me what the benefit would be. Connecting a TCP socket is very cheap. it's just 3 small packets.

levicki commented 4 years ago

what other protocols do you think should get that treatment? FTP, SMTP, telnet, SSH, SSL.

That's exactly the reason why you should not use well known ports for something other than their intended purpose. Using only ephemeral ports would solve that problem.

Connecting a TCP socket is very cheap. it's just 3 small packets.

In terms of network traffic? Yes. In terms of system resources? No.

arvidn commented 4 years ago

what other protocols do you think should get that treatment? FTP, SMTP, telnet, SSH, SSL.

That's exactly the reason why you should not use well known ports for something other than their intended purpose. Using only ephemeral ports would solve that problem.

I don't know what "that" refers to in that sentence.

The issue isn't about using (by which I assume you mean binding sockets to) well known ports. It's about other people listening on well known ports.

I don't think it's reasonable to dismiss their rationale without understanding it. (and if you do, please share!). I suspect it's to circumvent ISPs crippling network access.

In terms of system resources? No.

Would you care to elaborate? whose system resources? any why do you think the most effective way to mitigate using those resources is to use fewer retries? For example, lowering the connections_limit would also use less resources (locally).

levicki commented 4 years ago

What I am saying is -- if you refuse to connect to a well known port with a purpose of establishing p2p connection then you won't have a problem of fake peers on those ports. It is one possible solution.

People using well known ports to circumvent network policies of networks they do not own or control in my opinion do not deserve any sympathy or help to accomplish that. You will probably disagree with my stance, so let's agree to disagree and leave it at that.

If they want to use those ports and you don't want to prevent it, then at least consider allowing others to refuse connecting to peers using those ports.

As for resources? Socket descriptors and local ports on the OS level, connection states and NAT translations in every stateful firewall along the way, etc. Not a big deal, but I just wanted to point out that bytes sent/received are not the only resources used by repeated failed connection attempts.

arvidn commented 4 years ago

if you refuse to connect to a well known port with a purpose of establishing p2p connection then you won't have a problem of fake peers on those ports. It is one possible solution.

I would expect this primarily to be a problem for those web servers receiving incoming connections, much more than a problem for the people making them. At least as long as those connections time out correctly.

If they want to use those ports and you don't want to prevent it, then at least consider allowing others to refuse connecting to peers using those ports.

You seem to be under the impression that there's some feature missing in libtorrent. I don't think that's the case. There's a port-filter, similar to the IP filter. Any ports can be blocked.

levicki commented 4 years ago

Yet it is people making those connections who opened this issue, no?

As for libtorrent, I must admit I am not aware of the abilities. Is this port filtering also available and configurable in qBitTorrent?

If so, then the OP could just limit outgoing connections to ports >1024 to eliminate fake peers they are observing.

arvidn commented 4 years ago

As for libtorrent, I must admit I am not aware of the abilities. Is this port filtering also available and configurable in qBitTorrent?

I suspect not.

If so, then the OP could just limit outgoing connections to ports >1024 to eliminate fake peers they are observing.

The more important issue (in my mind) was that libtorrent had a bug where idle connections wouldn't time out correctly. That has been fixed though.

FranciscoPombal commented 4 years ago

The more important issue (in my mind) was that libtorrent had a bug where idle connections wouldn't time out correctly. That has been fixed though.

Yep.

I'm considering this sufficiently addressed, thanks everyone.

@levicki if you're interested, please open a feature request ~for the port filter~ - EDIT: I meant the ability to customize making connections to privileged ports, and there is already a PR for that - to be added to the advanced settings or something.

VolatileCable commented 4 years ago

I stated that it's not really fixed. While the connections do get closed, they just get reopened again shortly afterwards and the "fake" peers still take up a sizable amount of slots and load the servers; they just have a higher turnover now.

I don't get why you are so vehement against exposing this privileged port filter in QB. I, and the many other here, could just set this and be done with it.

But instead you just call it closed now, when it's not. And what would your solution be, implement even more workarounds and idle-timeouts for a problem that only happens on these low ports, where virtually no legitimate peers exists?

levicki commented 4 years ago

@VolatileCable

Can't you see they are doing it for your own good? They wouldn't want a clueless user shooting themselves in the foot with too many options, and fixing problems for real is obviously too hard.

NotTsunami commented 4 years ago

Since the patch seems to work as intended, after reading through this once again, I have changed my mind about whether blocking connections to privileged ports should be the default.

In fact, I don't think this should be a configurable settings at all unless someone can prove the following is a big deal affecting many users (I don't like the idea of making changes in qBittorrent just to appease anti-virus software, unless it is really needed):

I think one pragmatic point is that some anti-malware/anti-virus software really doesn’t like processes making connections to destination port 25 (SMTP)

@FranciscoPombal As I stated in the PR, the main purpose isn't to appease anti-virus software, it's to allow users to block incoming connections from servers listening on port 80. A port filter is even more subject to accidental repercussions from misconfiguration. This is more of an issue of if we don't need to make the connection, we shouldn't. This isn't something that would inhibit the swarm or negatively affect the swarm.

I don't need this tunable personally, so I don't care about the outcome too much, but I can't see the harm in allowing this to be configured.

arvidn commented 4 years ago

I don't get why you are so vehement against exposing this privileged port filter in QB. I, and the many other here, could just set this and be done with it.

I think the main risk with the port filter is that it will hide a serious underlying issue. The timeout issue exposed here is not just a problem for peers that aren't real peers, it's a big problem for peers that look a lot more legitimate as well.

If what you're seeing is indicating that the fail-counter and/or reconnect logic has problems, that's really important to fix. I would really like to know more about what behavior you're seeing.

The one reason I can think of why those peers would be retried indefinitely is if the tracker keeps returning them. Every time a tracker returns a peer, it's fail-counter is decremented by one (because maybe this time it's for real).

It would also be interesting to know what the local peer list size is, if there are in fact any peers that are being "pushed out" because of these connections (you seem to suggest that to be the case, or at least suspect it).

But instead you just call it closed now, when it's not. And what would your solution be, implement even more workarounds and idle-timeouts for a problem that only happens on these low ports, where virtually no legitimate peers exists?

I don't believe this problem happens only on these ports. If it happens there, it happens on all ports (but it may be harder to spot).

arvidn commented 4 years ago

it's to allow users to block incoming connections from servers listening on port 80

I believe you meant "block outgoing connections to servers listening on port 80", right?

This is more of an issue of if we don't need to make the connection, we shouldn't. This isn't something that would inhibit the swarm or negatively affect the swarm.

How can you know this? Maybe the fastest seeder is listening on a low port in some swarms. It's probably unlikely, but it seems risky to speculate without any data.

arvidn commented 4 years ago

@FranciscoPombal does qbt expose the torrent_status::list_peers or torrent_status::connect_candidates to users?

arvidn commented 4 years ago

here's another timeout fix: https://github.com/arvidn/libtorrent/pull/4577

Peers that don't respond with a bittorrent handshake are supposed to time out by the handshake_timeout setting, which defaults to 10 seconds. This wasn't working correctly.

NotTsunami commented 4 years ago

it's to allow users to block incoming connections from servers listening on port 80

I believe you meant "block outgoing connections to servers listening on port 80", right?

This is more of an issue of if we don't need to make the connection, we shouldn't. This isn't something that would inhibit the swarm or negatively affect the swarm.

How can you know this? Maybe the fastest seeder is listening on a low port in some swarms. It's probably unlikely, but it seems risky to speculate without any data.

You are correct. It is an assumption, yes. I'll leave the PR up until there's a definite resolution to this.

FranciscoPombal commented 4 years ago

@VolatileCable

Can't you see they are doing it for your own good? They wouldn't want a clueless user shooting themselves in the foot with too many options, and fixing problems for real is obviously too hard.

This snarky comment is completely uncalled for. There are people working to get this setting implemented, to the benefit of your use case. Furthermore, other underlying (and arguably more important) problems, are getting fixed for real in libtorrent as well. All while you sit back. Talk is cheap.

I stated I wouldn't want to have this as a configurable option, but as you could probably tell from my attitude towards the related PR, ultimately I don't mind if it gets implemented (i.e. I'm not vehemently against it). I just think the potential risk of a clueless user disabling connections to those ports and complaining about lack of peer connections (that could have been legit peers) is a greater liability than the trivial amount of system resources consumed by opening and closing a few connections to privileged ports that turn out to not be speaking the BitTorrent protocol, that's all. It's just an opinion.

@VolatileCable

I stated that it's not really fixed. While the connections do get closed, they just get reopened again shortly afterwards and the "fake" peers still take up a sizable amount of slots and load the servers; they just have a higher turnover now.

I don't get why you are so vehement against exposing this privileged port filter in QB. I, and the many other here, could just set this and be done with it.

But instead you just call it closed now, when it's not. And what would your solution be, implement even more workarounds and idle-timeouts for a problem that only happens on these low ports, where virtually no legitimate peers exists?

Again, not vehemently against having the option. But you don't seem to understand the point that this report is merely a symptom of more serious underlying issues in libtorrent that are now getting fixed. The implementation of a port filter option is not a real solution to the underlying problem, it just sweeps it under the rug. It's still getting implemented for the users like you who don't want to connect to privileged ports regardless of libtorrent handling it well after the bug fixes, so I don't think you have anything to complain about.

Plus, the fixes for libtorrent are not "even more workarounds and idle-timeouts for a problem that only happens on these low ports,", they are general fixes for stuff that was previously just wrong.

@NotTsunami

A port filter is even more subject to accidental repercussions from misconfiguration.

Agreed, I just mentioned the port filter in that comment by mistake.

How can you know this? Maybe the fastest seeder is listening on a low port in some swarms. It's probably unlikely, but it seems risky to speculate without any data.

It is an assumption, yes. I'll leave the PR up until there's a definite resolution to this.

This is why I changed my mind about what the default should be, and why ultimately I would prefer that this wasn't configurable at all (though I'm not vehemently against it, as stated previously).

It would seem that as long as the handshake bugs on the libtorrent side are fixed, this whole "fake peers on privileged ports" problem turns out to be a big fat nothingburger. Or, put another way, that a bad peer is a bad peer, regardless of the port number - nothing changes if it is privileged or not.