Tip of the day: Check out Special users on how to give trusted users/bots more rights without making them IRCOp. |
Anti-flood settings
This page describes the set::anti-flood block, which configures nearly all anti flood server settings in UnrealIRCd. See the Security article for a full list of all security measures.
Introduction and default settings
The anti-flood block has at least three groups:
- known-users: by default, this are users who are identified to services OR are on an IP that has been connected for over 2 hours in the past X days.
- unknown-users: all the users that are not known-users
- everyone: some settings are in this group, they apply to everyone due to technical limitations.
The idea is that unknown-users are less trusted so they get lower flood limits, while known-users get slightly higher flood limits. This behavior is the default (as shown further down).
You could also add extra custom groups, for example:
- You could create a new security-group called trusted-users with only a few trusted people or bots in it. See the security-group documentation on how to do that, but you could select users for this group by IP address, or by certificate fingerprint or by services account name, etc.
- Then in this set::anti-flood block you give trusted-users much higher flood limits and lower lag penalties. In 6.1.1 and higher you can also give them like a
set trusted-users { max-channels-per-user 25; }
.
In UnrealIRCd 6.0.8 there is also another "group" which isn't really a security group:
- channel: for channel anti-flood settings.
Most anti flood settings are set using rates. For example, a nick-flood setting of 3:60
means a maximum of 3 nick changes per 60 seconds.
Below is overview of the block and the default settings. Note that each settings is explained in detail later, further down.
set { anti-flood { /* The following limits apply to all users. They belong here * in the 'everyone' block and not anywhere else: */ everyone { connect-flood 3:60; handshake-data-flood { amount 4k; ban-action zline; ban-time 5m; } target-flood { channel-privmsg 45:5; channel-notice 15:5; channel-tagmsg 15:5; private-privmsg 30:5; private-notice 10:5; private-tagmsg 10:5; } } /* These are the "known users" who (if you use default * security group settings) are: registered users * who are identified to services, OR have been connected * to UnrealIRCd for longer than 2 hours. */ known-users { nick-flood 3:60; join-flood 3:90; away-flood 4:120; invite-flood 4:60; knock-flood 4:120; max-concurrent-conversations { users 10; new-user-every 15s; } lag-penalty 750; lag-penalty-bytes 180; } /* Everyone who is not in the known-users group. * These users have lower limits: */ unknown-users { nick-flood 2:60; join-flood 2:90; away-flood 4:120; invite-flood 2:60; knock-flood 2:120; max-concurrent-conversations { users 4; new-user-every 15s; } /* The following 2 items are new as of UnrealIRCd 5.2.1: */ lag-penalty 1000; lag-penalty-bytes 90; } } }
Settings that apply to everyone
connect-flood
This limits the number of connection attempts from each IP to count per period seconds, so it applies a limit per IP address. The default is 3 per 60. This feature is also referred to as connection throttling.
UnrealIRCd also has Connthrottle which will rate limit the number of connection attempts in total (so NOT per IP address).
Note that connection throttling is an important security measure. It provides primary and secondary protection against DoS, flood and brute force attacks, both for handshake and fully registered connections. If you disable it or set it very permissive (eg 6 per 60 seconds) then you severely degrade these protections.
If you want to exempt one or more IP's from connect-flood, then check out Except ban block and use type connect-flood there.
Example block with the default settings:
set { anti-flood { everyone { connect-flood 3:60; } } }
handshake-data-flood
NOTE: This settings is almost never changed. This flood protection is never hit by real IRC clients.
When a TCP/IP connection is accepted, the client sends some data during the IRC protocol "handshake" such as NICK, username and optionally IRCv3 CAP negotiation and SASL. After this handshake the client comes online. If more than the specified amount of data is sent during the handshake then a specified action is taken. This is a security measure to protect against arbitrary data floods, sending lots of bytes and consuming useless CPU and bandwidth. In all known cases less than 4k (4096 bytes) are sent during the handshake, so this allows us to be quite strict.
Example block with the default settings:
set { anti-flood { everyone { handshake-data-flood { amount 4k; ban-action zline; ban-time 5m; } } } }
target-flood
This flood countermeasure works differently than all the others. It does NOT set a maximum rate for sending per-person, it does NOT work per-source. It will limit floods to targets such as channels and persons at a maximum rate X:Y total. This so, for example for a channel, even if 100 people try to send data to the channel, the channel will never see more than the configured X lines per Y seconds in total.
The goal is to prevent flooding at HIGH rates only. To prevent flooding at such high rates that the client may no longer be capable of handling the traffic in terms of CPU usage (such as leading to a laggy interface) or even bandwidth. This is why the maximum rates are very high. We don't want this to be triggered in normal conditions even for extreme cases, such as channels that have a quiz/trivia bot. Even with this target-flood protection enabled, some IRC clients may still have problems with some types of traffic below the set maximum rate, we only do our best to limit damage to most clients this way.
This countermeasure is NOT for low-rate or medium-rate spamming/floods. If you want more strict channel flood control (and you probably do!), then use the very powerful and customizable channel mode +f as well.
There are 2 possible target types: channels and users. For each of those 2 there are 3 possible message types in IRC: privmsg, notice and tagmsg. Below you can see the default settings:
set { anti-flood { everyone { target-flood { channel-privmsg 45:5; channel-notice 15:5; channel-tagmsg 15:5; private-privmsg 30:5; private-notice 10:5; private-tagmsg 10:5; } } } }
When the target-flood limit is hit, we will drop the message. We do not kill the user, because the user who sent the 15th/60th/etc message could be a totally innocent user who only said stop this flood!. This is also why we don't offer a configuration option for killing either, since you may very well end up killing good people.
The limits apply to everyone (including channel operators), the only exception are IRCOps which are exempt if they have the immune:target-flood privilege (all IRCOps do, by default).
This anti-flood feature is handled by the targetfloodprot module which is loaded by default. You can use blacklisting in the configuration file to completely remove this anti-flood feature: blacklist-module targetfloodprot;
Settings that apply to groups
The following settings can be different for each security group. In most cases you will have two groups:
- known-users: identified to services OR are on an IP that has been connected for over 2 hours in the past X days.
- unknown-users: all the users that are not known-users
The criteria of who falls in known-users and who in unknown-users is decided by the security-group { } blocks. For example, if you want to put all your WEBIRC users in the known-users group, you can do so there in the security-group known-users { } block.
nick-flood
This limits the number of NICK changes a user can do. The default is 3 per 60 seconds for known-users and 2 per 60 seconds for unknown-users:
set { anti-flood { known-users { nick-flood 3:60; } unknown-users { nick-flood 2:60; } } }
join-flood
This settings works slightly different than others. It does not limit all joins to a maximum of X per Y seconds. Instead, this setting limits (re)joins to the same channel to X per Y seconds. Thus, it prevents PART+JOIN'ing the same channel repeatedly. The default is 3 per 90 seconds for known-users and 2 per 90 seconds for unknown-users:
set { anti-flood { known-users { join-flood 3:90; } unknown-users { join-flood 3:90; } } }
away-flood
This limits the number of AWAY changes a user can do. The AWAY command is used to mark someone as away or back from away. Usually, these aways+unaways are not very annoying, so by default we allow 4 per 120 seconds for both known-users and unknown-users.
set { anti-flood { known-users { away-flood 4:60; } unknown-users { away-flood 4:60; } } }
vhost-flood
This limits the number of times a user can unset their vhost or cloak (MODE yournick -x
or MODE yournick -t
). By default we allow 3 per 90 seconds for known-users and 2 per 90 seconds for unknown-users.
set { anti-flood { known-users { vhost-flood 3:90; } unknown-users { vhost-flood 2:90; } } }
invite-flood
This limits the number of /INVITE's a user can do. The default is 4 per 60 seconds for known-users and 2 per 60 seconds for unknown-users:
set { anti-flood { known-users { invite-flood 4:60; } unknown-users { invite-flood 2:60; } } }
knock-flood
This limits the number of /KNOCK's a user can do (rarely used command to knock on channels [s]he can't join). The default is 4 per 120 seconds for known-users and 2 per 120 seconds for unknown-users:
set { anti-flood { known-users { knock-flood 4:120; } unknown-users { knock-flood 2:120; } } }
max-concurrent-conversations
This configures the maximum number of conversations a user can have with other users at the same time. This is a protection measure against spambots who tend to mass /MSG
or /INVITE
many different users within a short period of time.
Let us explain with the default settings:
set { anti-flood { known-users { max-concurrent-conversations { users 10; new-user-every 15s; } } unknown-users { max-concurrent-conversations { users 4; new-user-every 15s; } } } }
A user may message up to max-concurrent-conversations::users different users without any problem. If he/she then messages another user this is only permitted at a rate of 1 every max-concurrent-conversations::new-user-every seconds.
For example, if the user belongs to known-users, then with a users set to 10 and new-user-every set to 15:
- UnrealIRCd will remember up to 10 users that the user is messaging
- The user can /MSG the first 10 users without any problem (eg: k1, k2, k3, k4, k5, k6, k7, k8, k9, k10)
- When trying to send a message to the 11th user (eg: k11) the user will have to wait up to 15 seconds before (s)he can do.
- Then the user can message the 11th user (k11)
- If the user then wants to send a message to a 12th user (k12, or even user k1 again which has by now dropped of the active 10 users list) then (s)he has to wait 15 seconds again
Since most users don't actively message many different users within a short period of time, this can be used as a way to detect bots/drones that flood users. The goal is to set the limit high enough for normal users to never experience this limit, yet low enough to be meaningful as a spambot countermeasure.
Also, note that this setting only affects user to user messaging and not messages to channels. This is because it is assumed that channel flood controls can take care of channel flooding.
The default settings are:
- UnrealIRCd 3.2.x - 4.2.1: 20 users, then new-user-every 15 seconds
- UnrealIRCd 4.2.2 - 5.0.9.1: 10 users, then new-user-every 15 seconds
- UnrealIRCd 5.2.x: For known-users: 10 users, new-user-every 15 seconds. For unknown-users: 4 users, new-user-every 15 seconds.
lag-penalty & lag-penalty-bytes
NOTE: These options only exists in UnrealIRCd 5.2.1 and later
Whenever a client executes a command, UnrealIRCd adds a "lag penalty" or "fake lag". This is an advanced and complex feature to understand but it ensures that a user can only execute a limited number of commands per timeframe and not flood commands at full speed.
IMPORTANT: If you simply want to allow a certain group of trusted users/bots to execute commands at higher rates, then see the Special users article where setting flood rates is explained under Overriding anti-flood settings. Or you can read below if you really want to know all the inner details.
For fake lag the rules are as follows:
- The lag formula is:
(1+floor(command_bytes/lag_penalty_bytes)+floor(message_tags_bytes/lag_penalty_bytes))*lag_penalty
milliseconds. Thefloor()
here means the value is rounded down, eg floor(171/90) is 1.9 but is rounded down to 1.- This means the user will receive a lag penalty of lag-penalty for every executed command
- Any IRC command that is bigger in size than lag-penalty-bytes will receive extra lag-penalty
- The total length of message tags (
message_tags_bytes
) is handled separately from the rest of the command (command_bytes
). If message tags are used then the client can use the first lag-penalty-bytes bytes "for free" (due to it rounding down to zero), eg if the client uses @label for everything they are not so punished for that.
- When artificial lag exceeds 10 seconds (10,000msec) then any further commands from the user will not be processed. They will placed in the receive queue (recvq).
- After 1 second has passed (so every second) the artificial lag is reduced by 1 second (1000msec) for every connected user.
- Once fake lag is 10 seconds or lower again, commands are read from the receive queue (recvq), parsed again and new fake lag is applied when needed.
Example:
- For unknown-users the default is a lag-penalty of 1000 and a lag-penalty-bytes of 90. If the user executes a command like
JOIN #test
then we can calculate how much the user will be lagged up. The commandJOIN #test
is 10 bytes. This results in a fake lag of:(1+floor(10/90))*1000 = (1+0)*1000 = 1000 msec
. - So if the user executes the command from above they get a fake lag of 1000 msec, so 1 second.
- If the user executes 10 such commands within 1 second, then they will have reached 10 seconds of fake lag
- Since the user has reached more than 10 seconds of fake lag, any further commands are not processed
- After 1 second, fake lag is decreased automatically by 1 second (fake lag is decreased by 1 second every 1 second for everyone), so they now have 9 seconds of fake lag, UnrealIRCd will now accept 1 new command again
- Say, the user now sends a long command of 200 bytes, then the lag fomula is applied:
(1+floor(200/90))*1000 = (1+2)*1000 = 3000 msec
. - The user has now changed from a fake lag of 9 seconds to a fake lag of 12 seconds (3000msec was added)
- Any new commands are not processed until fake lag is 10 seconds or lower again, so they are queued for the next 2 seconds
- If the user keeps sending commands that are not processed (so when fake lag is above 10 seconds), they will be put in the receive queue (recvq). If the user exceeds the class::recvq then the user may go offline with an Excesss flood error
This are the default settings:
set { anti-flood { known-users { lag-penalty 750; lag-penalty-bytes 180; } unknown-users { lag-penalty 1000; lag-penalty-bytes 90; } } }
In short:
- For unknown-users, as long as their commands are less than 90 bytes then they can do 1 big burst of 10 command in 1 second, after that they can only execute 1 command per 1 second, unless they stop sending commands for a while
- For known-users, as long as their commands are less than 180 bytes then they can do 1 big burst of 13 commands in 1 second, after that they can only execute 1 command per 0.750 second, unless they stop sending commands for a while
If you have a really trusted group of users that you would want to allow flooding at high speeds you can use something like:
set { anti-flood { flood-users { lag-penalty 100; lag-penalty-bytes 0; } } }
This way they get only 100msec of lag penalty. This means they can send 1000/10=10 command per second, and can even do an occasional burst of 10 times that (100 commands).