View Single Post
Old 10-07-2009, 01:49 AM  
Yil
Too much time...
 
Join Date: May 2005
Posts: 1,194
Default

There are a couple of points to consider when handling connections attempts. First off, there is no way short of writing a windows driver to reject a connection completely which is what I would really like to do. There used to be a way to do this years ago with winsock but then people started denial-of-service attacks against machines by initiating the TCP handshake and then not responding so MS changed the way windows works so it now always accepts TCP connections if a socket is listening for them. Therefore the server's only choice is to accept and then terminate the connection which is what happens when you get auto-banned for hammering the server.

I've taken the position that if you get auto-banned the server shouldn't respond with anything and just drop the connection. I've toyed with the idea of responding with a "you've been auto-banned" type message and the duration of the ban (it resets each attempt). I have no problem making the ban reset optional and/or making the reply optional or replying only some of the time, if people want that, but so far nobody's mentioned it. I don't think it would hurt to reply at least once and perhaps every 5 minutes there-after or something with a message to that effect. I don't believe anything should ever be returned in the case where the host is banned in Hosts.Rules.

I've also toyed with the idea of a script based accept/deny such as you are suggesting. The reason I decided against implementing it, at least until someone actually asked for it, was because external scripts are expensive to call and it's better left until later. It would be pretty easy to DDoS a server with a script handling raw connection attempts. This would be somewhat mitigated by having auto-bans checked first, but without actually knowing the username/password I figured it's best to avoid calling external scripts so I've tried to handle the common cases of rejecting valid users by allowing you to set for each user the number of connections per IP and the total number of logins.

Right now you can do exotic acceptance of login attempts by using a pre-cmd on the login or pass commands. You might also be able to do something like [iputs -nobuffer] followed by a [client kill $cid] in the OnFtpLogin event so you know you're dealing with a valid user yet you force them off. I'm not sure that's a good idea though as I'm not sure if that would always force the buffer to be completely sent in all cases which could look like a dropped connection rather than seeing a denied/logged off type message.

What I probably should do is test the return value of the OnFtpLogin event if defined and if error code text was output to the user (this would be your response to the PASS command) and an error was returned to gracefully force the user off without generating a login failed log entry as that would be up the script to do. That's going on my TODO list

Having given that rather lengthy response just to cover how things work right now and why, I should mention that also on the TODO list is script based manipulation of the auto-banned and permanent banned lists. I'd really like to be able to automatically add/remove addresses/masks into the server via a script...

Now, let me address the one problem I think you alluded to that might be driving the need for the accept/reject script. The ioftpd.log file is getting spammed? Check out the Max_Log_Suppression and Log_Suppression_Increment features.

Max_Log_Suppression: The maximum time (in minutes) to suppress rejection log entries (auto-banned, unmatched client, or Host.Rules) for the same reason from the same IP.

For some reason the Log_Suppression_Increment option doesn't appear in the .ini file (that's a bug) but it is documented in the Changelog...

Log_Suppression_Increment: the number of minutes to increase the delay between each suppressed message up to Max_Log_Suppression. Default is 1 additional minute per.

If you use an hour for max and an increment of an hour or so I think it should output 1 message per hour for a particular IP for each type of login error...

Would a modified version of OnFtpLogin and the log error suppression features already there solve your problem? Auto-ban manipulation (perhaps even with a limited choice of string responses) help? Should I provide a way to suppress auto-banned rejection messages completely?

I don't have any problem adding an OnConnection event like you requested, but I just want to make sure I'm helping you solve the problem you really want to solve.

--

You can't have connection specific global variables. However you can easily achieve this behavior. In ioYil I used two different methods depending on what I was doing. Just use something like foo-$cid as the name - tada! Or you can use an array of $cid->stuff mappings. However in the array case you must protect the array with a global [waitobject] lock to prevent race conditions on reading and then modifying the value across multiple threads.
Yil is offline   Reply With Quote