- Administrators
Archived
This topic is now archived and is closed to further replies.
- 0
Channel Flood Detection and Protection by myndzi
Asked by
chain
This topic is now archived and is closed to further replies.
Asked by
chain
Part 1 - Preface
Before I start, I would like to explain the purpose of this tutorial. This tutorial will deal with destructive floods targetted at channels and ways to detect and/or stop them. I specifically will not deal with what I refer to as "annoyance" kicks such as swearing, repeating (not in excess - repeating will earn bans with my methods anyway unless you specifically prevent it), color abuse, etc.
My goals are accuracy and speed - I want to react to valid threats as rapidly as possible, and to avoid kicking users who are not valid threats. A valid threat constitutes a flood that has the potential to disrupt a channel by disconnecting users or otherwise making the channel unusable (due to lots of text, etc).
I want to teach you how to make a flood protection script that does its job, and does it well.
I will not directly address personal flood protection, although it can be handled in a similar fashion. Bear in mind that bots that are used for user-access (i.e. op ops, keep bans, etc) must of necessity 'listen' to incoming privmsg or notice commands -- the best thing for a channel flood protection bot, however, is to run with SILENCE +!@* thus avoiding personal floods altogether. The /ignore command will not keep you from being disconnected with private messages/notices/etc. SILENCE, however, stops text on the server before it's even sent to you.
That all said, the rest of the tutorial will be in two main sections -- the first will describe two types of floods and explain why they work, and the second will discuss my own ideas about how to detect and deal with them. I will also discuss some IRC concepts that affect this subject (mostly to the detriment of effective flood protection =/) so familiarity with the IRC protocol is useful.
Lastly, the majority of my experience is with the DALnet network and Bahamut IRCD. Please inform me of any differences, changes, or incorrect statements I make concerning other IRCDs (or even Bahamut for that matter).
Part 2 - Floods: How They Work
There are two main ways to cause a user to be disconnected from IRC. Trojans and backdoors aside, one of these involves exploiting script triggers and their responses, and the other is based on brute force -- large amounts of data at high speed. The former method is easiest to exploit but, with the exception of 'standard' triggers such as !list, requires that the attacker know more about the target than the latter.
*** User has quit IRC (Excess Flood)
This message is caused when a client sends so much data to the server that the server disconnects the client. There are some things to know about how this works that also pertain to limits on what flooders themselves can do.
On an IRC server, there is a Send Queue and a Receive Queue for each client. The Send Queue (or SendQ) is used to store data that is waiting to be sent from the server to the client. The Receive Queue (RecvQ) is used to hold data that was received from the client for processing. Excess Flood is caused when the Receive Queue is full and the server reads data from the client. There are a few things that govern the way the Receive Queue works.
When the IRC server reads data from the client, the data goes into the RecvQ. The server will process the data a line at a time as commands. The server also keeps a variable associated with each client. This variable (dubbed 'since') will be less than or equal to the server's current time value while the client is idle. Each time the server reads and processes a command line from the RecvQ, it increments this value by 2 seconds. If the line is particularly long, the variable is also increased by $int($calc($len($1-) / 120)), where $1- is the line that was read. This is to say, for each multiple of 120 the length of the line is, an additional 1 second is added to the 'since' variable. When the server reads a command from your RecvQ, it skips processing that command if the 'since' variable is more than 10 seconds ahead of the current time.
In simpler terms, if you pasted 10 lines to a channel, 5 of them would show to everyone right away, and the other 5 would come through every two seconds or so.
Also, I'd like to note briefly that upon connecting to an IRC server (or at least a Bahamut one) you already have a few seconds against you -- where you might be able to fire off 5 commands instantly after being idle, immediately after connecting you can only send 3 or 4. This helps to limit what automatic flooders can do, and is worth keeping in mind. Additionally, some specific commands increase the 'since' value, though this may depend on the IRCD.
So. If you send stuff too fast (or too long, or both), it doesn't 'go through' right away. This means that your Receive Queue fills up FAST, since it isn't being emptied. If you have a script with a trigger (such as !list in some poorly written file servers) that doesn't have any form of flood protection, you are an easy target. All someone has to do is send !list a bunch of times to a channel you are in, and your script sends plenty of nice long notice lines in return -- to users who probably aren't even online anymore -- thus filling up its RecvQ.
What happens when your RecvQ is full? You quit IRC with the message: Excess Flood.
*** User has quit IRC (SendQ Exceeded)
This is the harder of the two flood types to achieve. Your Send Queue works like your Receive Queue without the extra flood code written in. The server has a queue of data it is waiting to send you, and when it fills up, you get disconnected. Having a fast connection helps avoid this, but you could have an OC3 and still be vulnerable. Your download speed isn't the only factor -- the IRC server's send speed is too. And the IRC server has a whole lot more to do than you do.
The IRC server has to loop through all its clients' Send Queues. It sends one line per client, then moves on. As well, server connections take precedence and are sent all the data in their queue regardless of how many lines. So, a server with lots of clients can't always keep up -- either in processing time or in upload speed (although servers generally have plenty of both).
In addition, if a channel is being flooded, the server has to send all the data that is coming through to all the clients on each channel, not just one person. Therefore, it's not as hard as you might think to flood a user, or a channel, off IRC this way.
One thing that gives a flooder a major leg up in this type of attack is control codes. Control codes alone won't do the trick, but control codes applied to text will -- you are probably familiar with the 'screen lag' that can be generated by gobs of bold characters alternated with text. If not, try this sometime in mIRC:
//var %t = $ticks + 4000 | while (%t > $ticks) { echo -a $str($+($chr(2),$chr(35)),400) | dec %i }
Likely you'll notice how the text display becomes noticeably slower. While mIRC is spending CPU time updating your screen, it's spending less time reading from the socket. This only helps your SendQ to fill up faster.
What happens when your SendQ is full? You quit IRC with the message: SendQ Exceeded.
You may have seen prefab combination floods, which use preset triggers in combination with long lines and control codes, like this:
<lamer13245> !list File Servers Online Ping Me flo0dflo0dflo0dflo0d...
These tend to work well versus poorly coded scripts that reply to any or all of the triggers, and with enough clones or enough time running rampant through the channel will disconnect people for SendQ as well.
One of the worst things is that often flood protection scripts, when faced with a large enough flood, will Excess Flood sending MODE commands (bans, channel locks..)! I've seen this happen in some well-known and recommended scripts, so don't think you're safe just because someone popular wrote the one you use
Anyhow, that about sums up this section... on to the next!
Part 2.5 - Keeping Your Bot Online
I know I said I wasn't going to talk about personal protection. I lied, a little
Your bot/script doesn't do anyone any good if it is offline or deopped. I'll leave it to you to code things to get it opped and in the right channels. I will offer some suggestions on keeping it online.
If your server offers SILENCE, use it. Silence !@* if you can, or !@* if you need to "hear" notices from say, ChanServ. Dalnet offers usermode +R, use it. Remember, /ignore doesn't help -- the most it can do is keep mIRC from spending CPU time updating your screen, but you are still going to be sent the data. Blocking data at the server, before it gets sent, is very useful for avoiding private floods.
Get a bounce on a shell with lots of bandwidth, and one that will DO something if somebody tries to "packet" you. ("Packeting" = Denial of Service or Distributed Denial of Service attacks that consume large amounts of bandwidth -- often via botnets, attacks such as smurf or bang, or both.) If a flooder can't get your channel because your script prevents them from getting a satisfying flood in, he may try to "packet" your script/bot offline in order to flood the channel.
Use some sort of buffering/queueing on ANY command that is triggered by user action. This includes bans from floods as well as !list or !op style triggers, it also includes CTCPs if the IRC server you use has no built in CTCP flood protection. Prioritized queues are best -- you want to be able to force channel locks to be sent before bans, bans before kicks, kicks before anything "non-essential".
Somewhat along the lines of the previous paragraph, use MODE queues to combine modes. Send six bans with each command, not one. You have room for four bans along with a channel lock such as +mi, but don't "wait around" to get four hosts to ban.
Also, regarding mode locks -- make absolutely sure that your script does not send say, five MODE commands full of bans and THEN try to lock. That's an extra 2 seconds you may not have. The best case scenario is for your script to lock the channel before setting any bans (if you decide to use bans?) at all.
Don't unlock the channel until everything else has been taken care of and you've had a chance to return to "idle" state. If a botnet is still going strong trying to flood you, you had better be ready to take another flood the moment your channel becomes unlocked. Along these lines, coordinate with other ops so that nobody's scripts conflict with each other -- someone unsetting a +i lock while your script is still in the middle of setting bans can be bad news for all of you.
Strip codes from incoming text anywhere, at least when there are lots of them -- don't use themes that use gobs of codes. Keep in mind that ctrl-k (color) does almost no damage. In order of seriousness, the control codes go about like this: bold, underline, reverse, color, reset. Bold and Underline are the critical ones, don't let your script display text containing lots of these.
Keep to a minimum number of channels. Each extra channel your script or bot is in gives a flooder another advantage over you. They can flood all your channels at once without much performance decrease, but you can't protect all of those channels as easily.
These are some things to keep in mind while designing your flood protection script. I thought I'd get them out of the way before I get into the guts of this tutorial so that they are already in mind when we come across places some of these ideas could be used.
Part 3 - Reaction
Reaction time is everything. Reaction depends on how well you can detect floods and discriminate between floods and regular channel text. What I'm going to teach you here is aimed to increase reaction times and maintain the ability to discriminate.
There are two things you are likely to see with floods. There is the single-host flood, where a single client (often with a couple clones on the same host) joins your channel and floods. It may or may not disconnect and repeat... if it doesn't disconnect, it will be even more ineffective of a flood than it already is This type of flood only really has a hope of causing someone to Excess Flood via trigger abuse, and is easy enough to catch. Your script should not cause a channel lock for this type of flood, all it needs to do is ban the flooder. On some networks, there is a feature called "bquiet" which will make a banned user unable to talk on the channel. This is useful... if your server doesn't have this, you will want to arrange a swift kick for the offender and any clones.
Speaking of kicks, for the most part you can delay your kicks until well after everything else is taken care of. Almost any automated flood will cause the flooding users to leave or quit repeatedly, and a ban in place will keep them from coming back (except in some instances with lag involved -- more later). Having a separate bot set to filter-kick users on bans is an excellent setup.
If a flood isn't generated from a single host with a script, it is likely a botnet or proxy flood. These can have large numbers of clones and need to be dealt with very rapidly. Bots in a botnet can be used for proxies, but there are also lists of various types of proxies all over the web. Proxy floods offer the flooder more control, but he needs to know what he is doing to make them effective. Botnet floods are often automated, which makes the impact less as the bots tend not to all begin their flood (or maintain it) at the same time / speed.
With these things in mind, my preferred action is to set a single ban on single-host floods, but to lock the channel if two or more hosts are involved. The channel lock should be sent before any bans that have been accumulated -- reaction time, as I've said, is critical.
I try to always be on servers with low lag to my client. 200ms is decent, but I prefer 100 or less. In flood circumstances, the server has a LOT to do, therefore even if I were to send the command MODE #chan +mi the INSTANT the first clone joined, it could take much more than 200ms for the command to be enacted.
Here is a real-world example from a log from an older version of my bot:
(09:36.28) 0 *** Channel being locked!! (09:36.33) 0 *** ComputerEyes sets mode: +mi
It took five seconds from the time my bot sent the MODE command until the mode change was enacted. The bot's lag to the server was about 400ms at the time. In that time, a total of 93 bots joined and flooded the channel. To put this in perspective -- my bot sent the MODE lock after the 4th line of flood text. (Reaction times were improved later The bot set two bans before the mode lock -- one flood bot flooded way before the others and was banned singly.
Hopefully these kinds of circumstances are rare, but when you are imagining the scope of things, keep in mind that any decent botnet has well more than enough bots to fill your channel's ban list and still flood you pretty hard with the ones you can't ban. I've seen lists of 200-300 connectable proxies on Dalnet, although Dalnet now scans all the common proxy ports, and I've seen or heard of botnets with populations in the thousands. And of course, botnets can be used as undetectable proxies.
Now, most people won't ever have to deal with floods of this magnitude, and the largest botnets are often used for "packeting" rather than flooding, but the same principles that I am about to outline apply for 50 bots or 5000.
Part 3.1 -- Detection and Discrimination
How is all that for preliminary rambling? Now we get into the good stuff! By now you should have an idea of: how floods do damage, some ways you can protect yourself, and why reaction time is important. Now I'm going to go into how you can protect others too.
How do you go about discriminating between valid text and "dangerous" text? You look at characteristics. The only way for a flood not to be caught is to imitate "regular" text to such a degree that it no longer becomes "dangerous" to users. This more or less defeats the purpose of flooding, except to preserve it as an annoyance. Annoyances are easy to deal with manually or with other scripts -- mass floods more or less require script intervention.
"Regular text" in social channels generally is short, relatively free of codes, not often repeated (except sometimes with things like 'lol') between multiple people, and generally has reasonable delays between typed lines. People do not often speak immediately after joining a channel.
"Regular text" in some other channels, such as file serving channels, may have text repeated at long intervals, contain long lines and lots of colors, but relatively few other codes, many lines will be similar but not identical. Most scripts do not advertise immediately upon joining, but some will. Some people will also have more than one script responding. (I've seen file servers advertise twice, I let them get banned rather than change thresholds to suit users who can't even get their own script under control.) I've also seen fileserver ad floods, so don't be too lenient on these guys.
"Flooder text", in the context of this document, generally follow a very similar pattern: a flood host will join the channel, immediately send its flood text (often 1-3 lines, usually 2), and then part, quit, or close the socket (generating a quit). Flood text can be sent in privmsg, notice, ctcp, etc. There are various ways to optimize the result of this phase, and I will deliberately avoid going into them; I don't believe the small benefit of this knowledge would help enough to justify making it easily publicly available.
Notable differences: flood text will usually begin immediately after joins, will be repeated many many times between multiple hosts, and will often evidence many other tipoffs, such as large control code content, long text length, multiple triggers (sometimes), and repeated text within the string (flo0dflo0dflo0d). I have some code that will check for the last, which I will include near the end of this tutorial.
I do not advocate punishing a user for any one of these things alone, but all of them combined will almost guarantee you a flooder. Some exceptions to watch out for include file server triggers and many scripts which seem to like to advertise themselves immediately upon joining a channel with plenty of color codes and whatnot (I'm using Al-Hasif Script).
Flood text CAN be short, such as that in CTCP floods.
While I'm on the topic of CTCP floods, I'd like to point something out in the versions.txt file for mIRC 6.0. Previous to mIRC 6.0, some problems were evident in mIRC (which I discovered, and know of at least one other person who has as well).
187.$chan is now filled for the on ctcpreply event if it was a channel ctcp message.
The on ctcpreply event did not fill the $chan identifier. Although CTCP replies never have a good reason to be sent to a channel, one of the prime sources for exploits and other malicious things comes from assumptions in programming. No mIRC script could properly respond to a user CTCP Reply flooding a channel because none of them would associate the flood with the channel. $target was the giveaway but I don't know of anybody who made use of it.
188.Ctcp messages that use an invalid format are now treated as plain text, and will trigger script events.
Before mIRC 6.0, there were also ways of misformating CTCP messages so that mIRC did not display them at all, and therefore could not react to them either. Both of these problems are now fixed, and I recommend that you use mIRC 6.0 at least to avoid being vulnerable because of either of these things.
In addition, any script you write should have flood protection on every single event that generates a response from your script due to outside user input, especially if there's no reason for anyone to provide said input. Many, many scripts are vulnerable to CTCP reply floods, especially CTCP PING reply floods, because of autopingers. I can't remember the last time I saw a well-written autopinger, and they all blithely reply with a wonderfully long notice to a very short command. Autopings are one of the easiest triggers to exploit with the exception of !list.
Be sure to write in CTCP Reply flood protection towards channels and users just as you might write in "regular" text flood protection. CTCP Replies are no different than any other text.
Part 3.2 - Where's the Code?
Rather than present you with my (admittedly ugly) bot code, I am going to instead describe exactly how it works, with code samples that hopefully don't look too much like an alien language.
The first generation of my flood protection bot, ComputerEyes, was pretty much a test of a concept. I wanted to see if my ideas regarding flood detection were any good. So, it started out small, clean, and simple -- and it worked great.
I wrote two things:
A JOIN flood detector
A repeat flood detector
I made use of the inc -z command all over the place, and pestered Khaled to add an hinc so that I could clean up the ugly variables and $+'s. inc -z increases a variable, and tells mIRC to decrease that variable once every second until it reaches zero, then unset that variable. I'm going to go ahead and recreate the basic form of my bot here:
on @*:join:%protect_chans:{ inc -z %protect.j. $+ $chan $+ . $+ $site 7 if (%protect.j. [ $+ [ $chan ] $+ . $+ [ $site ] ] > 13) kickban $chan $nick } ctcp *:*:#:{ haltdef protect_check $1- } on *:text:*:%protect_chans:{ haltdef if ($me !isop $chan) return protect_check $1- } on *:notice:*:%protect_chans:{ haltdef if ($me !isop $chan) || (. isin $nick) || (($network == dalnet) && (ChanServ == $nick)) return protect_check $1- } on *:action:*:%protect_chans:{ haltdef if ($me !isop $chan) return protect_check $1- } ;call this alias for text in PART and QUIT messages too alias protect_check { ;so chan staff doesn't get mad at me for kickbanning them :) if ($nick isop %c) || ($nick isvo %c) return ;i use a hash of the text to find repeats -- strip the text of codes, ;make it all lowercase, and truncate to 400 chars; this helps to ensure ;that cosmetic variations in flood lines are minimized. var %h = $hash($lower($strip($left($1-,400))),32) ;keeps the repeat variable from getting ridiculously high as it is wont in large floods ;the cap on this value will play a useful role in the more "complicated" version of my ;script -- as it decreases once per second, the higher it is allowed to get, the longer ;it is before saying text that generates this same "fingerprint" will be safe, i.e. not ;cause a ban. ;lastly, this variable stores global repeats -- anybody saying this text will inrease it if (%protect.r. [ $+ [ $chan ] $+ . $+ [ %h ] ] < 70) inc -z %protect.r. $+ $chan $+ . $+ %h 2 ;now for the client-specific flood variable ;first, we increase it by the global repeat value (which gets bigger with each repeat) inc -z %protect.r. $+ $chan $+ . $+ $site $+ . $+ %h %protect.r. [ $+ [ $chan ] $+ . $+ [ %h ] ] ;also, we increase it by the client-specific join-flood value -- if the client just joined ;it will take a big hit to its flood numbers: inc -z %protect.r. $+ $chan $+ . $+ $site $+ . $+ %h %protect.j. [ $+ [ $chan ] $+ . $+ [ $site ] ] ;there are other factors i ended up adding here; they will be discussed later but i'm ;leaving them out of the code ;client specific flood value too high? get rid of them! if (%protect.r. [ $+ [ $chan ] $+ . $+ [ $site ] $+ . $+ [ %h ] ] > 19) kickban $chan $nick ;pseudo-code to follow: ;if (lock condition) && (lock variable unset) { lock channel | set lock variable } ;i won't go into this because then i'd have to also write in my ban and kick queues, channel ;flood value stuff, and more }
The preceding code may or may not work, it's taken from my bot and drastically simplified. I do not remember why I used an if line rather than on @*:text:etc, so don't ask me about it It's just there to give you an idea of what's going on. I had an alias to do the job of inc -z and the [ $+ ] stuff, but found it more cryptic to read than just writing out the code itself.
Okay, what is all that garbage!?
Basically, I keep a few variables for things. These variables are constantly shrinking automatically, so over time they will empty themselves. But, when things keep happening that increase them, they are eventually pushed over a threshold. When this happens, the script reacts. For example, in the JOIN flood code, the threshold is 13. Each time a user joins, the variable associated with joins for a given $site value is increased by 7. Two joins within less than a second will cause the value to pass the threshold. Three joins within 7 seconds will do the same, as will four joins in 14 seconds, etc.
The join value directly affects the flood value of a line of text. Each time text with a certain hash is said, the corresponding channel variable is increased. This indirectly affects the flood value of a line of text. Continuing to repeat a certain text phrase (more often than once every two seconds) will cause a client's flood value to rise exponentially. Text within 7 seconds of a join also takes a minor to major hit, depending on how soon after it was said.
When a client's flood repeat value is over the threshold, that client is kickbanned. Any other clients saying the same text will also be kickbanned in short order.
In the actual bot I have, I make protect_check take a channel as a parameter. This is so that I can call it from the on quit event for text in quit messages. I also call it from on part. I modified that in the example code to help improve its already dubious clarity
Because this script has evolved far from its starting point, the basis of the code that controls when a channel is locked is in the ban queue code. Using a similar inc -z method, I keep a value for the number of bans queued in a channel. When the number of bans becomes large enough, the channel is locked. I keep a variable set after sending a channel lock so that my bot does not attempt to send the lock more than once. When certain modes (in this case, +i) are unset, the variable is too.
What are these complexities you speak of?
Well, in addition to increasing the client flood value based on channel repeats and the join value, I added in the following factors:
Text length
Repeated text content (Left-to-right)
Repeated text content (Right-to-left)
Control codes
Any of these can affect the increase of the client flood value by a limited number. The maximum increase varies per item, and would make a nice option if it was adjustable. At the moment, the only way to adjust my bot's settings, however, is to edit the code.
Text length is fairly straightforward, depending on how much weight you want that to carry, an easy formula to use is $int($calc($len(text) / N)). I used N = 100, so 450 characters would make for an increase of 4.
Repeated text content refers to things such as 'flo0dflo0dflo0d'. That string would contain 3 repeats from either direction. Right-to-left is the most important, because of floods that include text triggers and such at the start, but then have repeated text afterwards. I added the Left-to-right checking upon seeing a flood that did this in reverse. This is the code I used to check for that:
alias rchk { var %t = $strip($1-), %a = $right(%t,1), %i = $calc($len(%t) - 2), %b while (%i) { if ($mid(%t,%i,1) == %a) goto rc2 | dec %i } return 0 :rc2 | inc %i | %b = $mid(%t,%i) | return $pos(%t,%b,0) }
The copy of mIRC running my bot does not strip control codes automatically. I use custom echos in a sort of "theme" to include debug information, and to allow my script the ability to count how many and what kind of control codes are present, rather than have mIRC strip them out before I get a chance to see. The identifier I made to return a value for control code content is somewhat abstract:
alias cchk return $int($calc((1 - $len($strip($1-,bur)) / $len($1-)) * $len($strip($1-)) / 2))
I hardly remember why I did that anymore, but it appears to take into account both the percentage of the text containing codes and the length of that text without codes. Keep in mind that control codes are useless if they have no text to apply themselves to.
There are other planned additions that I never got around to, these include $site blacklists for repeat offenders (especially useful to keep track of hosts that are involved in mass floods, can lead to an early channel lockdown) and a text blacklist, where the hash of a certain text string that is used in separate floods leads to more likely bans or channel locks. You'd have to be careful with that last, anyone who understood how it worked could flood with things like 'lol' and cause undesired results.
Hopefully all of that isn't too hard to understand. Please leave me feedback and suggestions on how to make it more easily accessible -- which parts to change, leave out, explanations to add, etc.
Part 3.3 - How to React
What you do about what you see is important too. Obviously you want to ban offenders and lock the channel when necessary. But often people don't put enough thought into even simple things like this. As I said before, I recommend locking if you have to ban more than one client for the same flood, and don't send more than one or two MODE lines before you do so, if you're going to. If you're not sure, wait a little and see.
Appropriate mode locks -- Dalnet has modes +M and +R. +M allows only registered and identified users to talk on the channel, and +R allows only registered and identified users to join the channel. I do not recommend using either of these. As I mentioned earlier, assumptions lead to exploitability: you don't see any registered-nick floods now, but what's to say there can't be any? I can see no reason to assume that. In my opinion, nothing can beat +mi. Nobody talks, nobody joins. Simple and effective. Your users aren't going to be talking much in the middle of a flood anyway, so they aren't losing much.
Now, I'd like to address something here that I haven't yet, and that is network lag. Some flooders will purposefully choose to connect their bots to laggy servers -- or even chose a server and attack it with DoS or DDoS attacks to make it laggy -- so that their floods are more effective. Here's what happens.
When you set mode +mi, it takes effect on your server (the sooner the better), but it also has to send the MODE command out to the other servers, so that it is the same everywhere. This doesn't always happen instantly, to my great annoyance, and the result is that flooding hosts can still join and part the channel, even after the modes +mi have been set. This is because the +i mode hasn't made its way to the server the flood bots are connected to. I can think of no easy way around this except to make sure your protection bot is located near the center of the network, or to locate more than one bot on different servers at opposing servers.
Although the local server cannot deny JOIN commands issued from other servers, it CAN refuse to broadcast PRIVMSG and NOTICE commands. This means that the +m will keep the flooders silent, at least on any servers which the mode lock has propagated to so far.
What does this mean? Mode +m is important. It should remain until flood bots are no longer joining your channel. After this happens, it is ok to remove the +m mode so that users already in the channel can talk, however it is usually a good idea to leave the channel +i for a while. How long is up to you, I recommend making it at least 10 seconds after finishing all other commands (such as bans and/or kicks). I use a progression whereby the channel mode goes like this:
+mi
-m
+R-i
-R
What you use is up to you, but don't make any assumptions I considered writing a script to find common masks between multiple hosts (for bots with nicks that all contain a certain word or phrase), but decided it wasn't worth it. It is, however an available option.
Combining modes -- this is important for your bot. Do you want to ban every user in a large flood? If so, you're going to want to be setting 6 bans per MODE command or it will take a long time. $modespl in mIRC will tell you how many modes you can set per line, if the server provides that information. It occurs to me that banning hosts only serves to slow the largest floods, but it's probably worth it anyway. Small floods will be entirely blocked, large ones will at least not be able to join their strongest/fastest flood bots.
My own bot did not bother unsetting its own bans - it relied on ops or other bots to do that job. That decision is up to you. An eggdrop bot that filter-kicked bans and unset bans after a time, as well as does user access and is configured to op the flood protection bot on join would make a nice complimentary combination with the kind of bot I'm describing.
I won't give you any code for command queuing and combining modes -- this tutorial is long enough already. In addition, the code I've been using is lacking and I have a better system in mind but incomplete. Sorted @windows would probably be a good resource, with the first token being a number to affect priority.
Part 4 - 'Lines per Second' Rant
I have a very low opinion of this method of 'flood protection'. Even when written correctly, it is generally configured incorrectly, and it's the users who suffer. Some of the ops don't even care. Partly, this is because people lose sight of the goal. What is a flood? Is it three lines in five seconds? No. That's not even an annoyance, unless the text is really obnoxious. Is it pasting text from somewhere else? No. That can be an annoyance with enough data, but there's an easy fix - kick them once, and they won't rejoin until they are done pasting. All the PRIVMSG commands have to go through before the JOIN does. 4 lines within 1 second should be sufficient to detect this, and it's one of the few uses I can think of for this method.
So you have a script you like, and it uses lines per second to detect floods. How do you configure it? A high number of lines in a low number of seconds. Why would you ever want the number of lines to be LESS than the alotted time? Is someone typing rapidly going to cause people to be disconnected? Is it doing any damage to your channel? Probably not. Is a real flood going to be so slow that you have to configure your settings like that? Probably not.
Keeping in mind what I said about how many commands you can send before the server stops you, 2-3 lines in 1 second is likely to be a good setup. Flooders aren't going to wait a second per line. Unfortunately you can't factor joins, parts, or quits into this equation. For a flood worthy of locking the channel, I'd say that 10 lines in 2-3 seconds is sufficient. If your channel has a lot of stuff going on, that may need adjusting, but the important thing is many lines, few seconds. Heavy floods can easily achieve that. The more lines you use, the longer before your script reacts, so the higher the number, the more accuracy, and the slower the response. If you've got it the other way around, do some thinking.
Part 5 - Summary
Hopefully I've managed to impart to you through the course of this document an understanding of how and why floods work, the knowledge that there are better ways to do flood protection than simply "lines per second", some ideas on how you can discriminate between real users and flood clones. I hope that you will use this as a stepping stone, and put a little effort into making a script that is above par. Realize that flood protection isn't the only thing you can do this with.
Link to comment
Share on other sites