Re: [Proftpd-user] ProFTPD 1.3.7a : Various BanOnEvent ClientConnectRate rules in server config section

"De Gaaij, Pieter" <[email protected]> Mon, 5 Jul 2021 14:36:02 +0200
Newsgroups gmane.network.proftpd.user
Message-ID <[email protected]>
All,

I have setup debugging on ProFTPD and even trace logging.

 From the debug log, I learned that the Client IP's are classified in 
the right way.
For instance from the debug log :
2021-07-05 12:35:53,356 <dropserver> proftpd[28587] <dropserver IP> 
(<client 1 IP>[<client 1 IP>]): session requested from client in 
'freq_conns' class
2021-07-05 12:36:34,702 <dropserver> proftpd[28696] <dropserver IP> 
(<client 2 IP>[<client 2 IP>]): session requested from client in 
'morefreq_conns' class

The *mod_ifsession* is also called, see below:

2021-07-05 13:41:15,391 <dropserver>proftpd[8741] <dropserver IP> 
(<client 1 IP>[<client 1 IP>]): performing module session initializations
2021-07-05 13:41:15,391 <dropserver>proftpd[8741] <dropserver IP> 
(<client 1 IP>[<client 1 IP>]):mod_ifsession/1.3: <IfClass other_conns> 
not matched, skipping
2021-07-05 13:41:15,391 <dropserver>proftpd[8741] <dropserver IP> 
(<client 1 IP>[<client 1 IP>]):mod_ifsession/1.3: <IfClass 
morefreq_conns> not matched, skipping
2021-07-05 13:41:15,391 <dropserver>proftpd[8741] <dropserver IP> 
(<client 1 IP>[<client 1 IP>]): mod_ifsession/1.3: merging <IfClass 
freq_conns> directives in

However, in the server config session, where I have configured the 
BanOnEvent rules, it seems that the ifClass directives doesn't work.
Because, although I have configured 3 different BanOnEvent rules for the 
3 different Classes, *only* the first statement/occurrence of the 
BanOnEvent rule is selected by ProFTPD, regardless of the Class during 
the login session. So, it looks like that the ifClass statement is not 
recognized, but only the setting of the BanOnEvent statement. And if you 
change that 15/min with 50/min, then all the various client-classes are 
limited to the 50 connections per minute.

I have checked that with the ftpdctl command, and always the first 
BanOnEvent statement is in effect for different IP-classes:

Client 1 is part of the Class "freq_conns"
Client 2 is part of the Class"morefreq_conns"

# ftpdctl -s <socket file> ban info -v -e
ftpdctl: No bans
ftpdctl:
ftpdctl: Ban Events:
ftpdctl:   Event: ClientConnectRate
ftpdctl:   Source: <client 1 IP>
ftpdctl:     Occurrences: 1/*15*
ftpdctl:     Entry Expires: 42 seconds
ftpdctl:     <VirtualHost>: ProFTPD RHEL Test Dropserver-SFTP 
(<dropserver IP>#22)
ftpdctl:   Event: ClientConnectRate
ftpdctl:   Source: <client 2 IP>
ftpdctl:     Occurrences: 1/*15*
ftpdctl:     Entry Expires: 57 seconds
ftpdctl:     <VirtualHost>: ProFTPD RHEL Test Dropserver-SFTP 
(<dropserver IP>#22)

This is what I have put in the server-config section of my 
ProFTPD-config file :

LoadModule                      mod_sql.c
LoadModule                      mod_sql_sqlite.c
LoadModule                      mod_sftp.c
LoadModule                      mod_auth_otp.c
*LoadModule                      mod_ban.c*
LoadModule                      mod_ctrls_admin.c
LoadModule                      mod_quotatab.c
LoadModule                      mod_quotatab_file.c
*LoadModule                      mod_ifsession.c*

.....................
.....................

<Class freq_conns>
         From 1.2.3.4       # A test server "clv100764" for Docbase to 
test this setup.
</Class>

<Class morefreq_conns>
         From 5.6.7.8       # clv100838 = Apigee T&I server.
</Class>

<Class other_conns>
         From !1.2.3.4      # A test server "clv100764" for Docbase to 
test this setup.
         From !5.6.7.8      # clv100838 = Apigee T&I server.
         From 10.0.0.0/8         # All 10-addresses.
         satisfy all
</Class>

.............
.............

<IfModule mod_ban.c>
         BanEngine               on
         BanLog                  <LOG-dir>/proftpd_ban.log
         BanTable <ETC-dir>/proftpd_ban.tab

         # Allow the FTP admin to manually add/remove bans
         BanControlsACLs         all allow user root,proftpd
         # If the same client reaches the MaxLoginAttempts limit 10 times
         # within 1 minutes, automatically add a ban for that client that
         # will expire after two hours.
         #
         BanOnEvent MaxLoginAttempts 2/00:05:00 01:00:00 "You are banned 
out for 1 hour"
         BanOnEvent RootLogin 1/00:01:00 02:00:00 "Stop connecting with 
root"
         BanOnEvent mod_auth.root-login 1/00:01:00 02:00:00 "Stop 
connecting with root"

         # Define that a banned client host in one VirtualHost is also 
banned in the other VirtualHost.
         BanOptions              MatchAnyServer

         <IfClass freq_conns>
                 # Set a specific ClientConnectRate for Client 
IP-classes that normally do not connect frequently
                 # or that are unknown users/client-IP's.
                 BanOnEvent ClientConnectRate *15*/00:01:00 02:00:00 
"Stop connecting frequently" *<--- **the first statement/occurrence of 
the* BanOnEvent
         </IfClass>

         <IfClass morefreq_conns>
                 # Set a specific ClientConnectRate for Client 
IP-classes that normally do not connect frequently
                 # or that are unknown users/client-IP's.
                 # Set a specific ClientConnectRate for Client 
IP-classes that normally connect very frequently
                 BanOnEvent ClientConnectRate *20*/00:01:00 02:00:00 
"Stop connecting frequently"
         </IfClass>

         <IfClass other_class>
                 # Set a specific ClientConnectRate for Client 
IP-classes that normally do not connect frequently
                 # or that are unknown users/client-IP's.
                 # Set a specific ClientConnectRate for all other  
Client IP's
                 BanOnEvent ClientConnectRate *5*/00:01:00 02:00:00 
"Stop connecting frequently"
         </IfClass>
</IfModule>

However, configuration of "BanEngine on" or "BanEngine off" _can _be 
regulated by means of Class: you can put Banning off or on for specific 
IP-Classes.
So this works fine, if put in the Global Section of the VirtualHost Section:

                 <IfModule mod_ban.c>
                         <IfClass freq_conns>
                                 # Set a specific ClientConnectRate for 
Client IP-classes that normally do not connect frequently
                                 # or that are unknown users/client-IP's.
                                 BanEngine       on
                         </IfClass>

                         <IfClass morefreq_conns>
                                 # Set a specific ClientConnectRate for 
Client IP-classes that normally do not connect frequently
                                 # or that are unknown users/client-IP's.
                                 # Set a specific ClientConnectRate for 
Client IP-classes that normally connect very frequently
                                 BanEngine       on
                         </IfClass>

                         <IfClass other_conns>
                                 # Set a specific ClientConnectRate for 
Client IP-classes that normally do not connect frequently
                                 # or that are unknown users/client-IP's.
                                 # Set a specific ClientConnectRate for 
all other  Client IP's
                                 BanEngine       off
                         </IfClass>
                 </IfModule>

This is the proftpd -V output:

So the mod_ifsession is the last one of the shared-modules.
Also in the ProFTPD config file, it is the last specified DSO-module.

Compile-time Settings:
   Version: 1.3.7a (maint)
   Platform: LINUX [Linux 3.10.0-1160.15.2.el7.x86_64 x86_64]
   Built: Thu Mar 25 2021 17:26:22 CET
   Built With:
     configure  '--disable-sendfile' '--localstatedir=/var/run' 
'--enable-ctrls' '--enable-openssl' '--enable-quotatab' '--enable-nls' 
'--enable-dso' '--with-lastlog=/export/org/proftpd/var/lastlog' 
'--with-modules=mod_readme:mod_ident' 
'--with-shared=mod_sql:mod_sql_sqlite:mod_sftp:mod_tls:mod_auth_otp:mod_ctrls_admin:mod_quotatab:mod_quotatab_file:*mod_ban:mod_ifsession*' 
'--prefix=/usr/local'

   CFLAGS: -g2 -O2 -Wall -fno-omit-frame-pointer 
-Werror=implicit-function-declaration
   LDFLAGS: -L$(top_srcdir)/lib -L$(top_builddir)/lib  -rdynamic
   LIBS:  -lssl -lcrypto -lsupp -lnsl -lresolv -lresolv -lcrypt -ldl

   Files:
     Configuration File:
       /usr/local/etc/proftpd.conf
     Pid File:
       /var/run/proftpd.pid
     Scoreboard File:
       /var/run/proftpd.scoreboard
     Header Directory:
       /usr/local/include/proftpd
     Shared Module Directory:
       /usr/local/libexec

   Info:
     + Max supported UID: 4294967295
     + Max supported GID: 4294967295

   Features:
     - Autoshadow support
     + Controls support
     + curses support
     - Developer support
     + DSO support
     + IPv6 support
     + Largefile support
     + Lastlog support
     - Memcache support
     + ncursesw support
     + NLS support
     + OpenSSL support (OpenSSL 1.0.2k  26 Jan 2017, FIPS enabled)
     - PCRE support
     - POSIX ACL support
     - Redis support
     - Sendfile support
     + Shadow file support
     - Sodium support
     + Trace support
     + xattr support

   Tunable Options:
     PR_TUNABLE_BUFFER_SIZE = 1024
     PR_TUNABLE_DEFAULT_RCVBUFSZ = 8192
     PR_TUNABLE_DEFAULT_SNDBUFSZ = 8192
     PR_TUNABLE_ENV_MAX = 2048
     PR_TUNABLE_GLOBBING_MAX_MATCHES = 100000
     PR_TUNABLE_GLOBBING_MAX_RECURSION = 8
     PR_TUNABLE_HASH_TABLE_SIZE = 40
     PR_TUNABLE_LOGIN_MAX = 256
     PR_TUNABLE_NEW_POOL_SIZE = 512
     PR_TUNABLE_PATH_MAX = 4096
     PR_TUNABLE_SCOREBOARD_BUFFER_SIZE = 80
     PR_TUNABLE_SCOREBOARD_SCRUB_TIMER = 30
     PR_TUNABLE_SELECT_TIMEOUT = 30
     PR_TUNABLE_TIMEOUTIDENT = 10
     PR_TUNABLE_TIMEOUTIDLE = 600
     PR_TUNABLE_TIMEOUTLINGER = 10
     PR_TUNABLE_TIMEOUTLOGIN = 300
     PR_TUNABLE_TIMEOUTNOXFER = 300
     PR_TUNABLE_TIMEOUTSTALLED = 3600
     PR_TUNABLE_XFER_SCOREBOARD_UPDATES = 10

So my *questions *are:

1) Did I configure the BanOnEvent rules on the wrong place (I found out 
that you only can configure them in the Server-config section) or 
otherwise incorrectly ?
2) Or, isn't it possible at all to configure different BanOnEvent rules 
with ifClass directives ?
3) If not, is it possible to put this as a new feature in the ProFTPD 
next release ?

I could send you my ProFTPD config file, debug and trace logs if that 
could give more clarity.

I hope that someone could have a look at it and have an answer on my 
questions.

Thanks in advance,

With regards,

Pieter de Gaaij

On 21 Jun 2021 21:34, De Gaaij, Pieter wrote:
>
> TJ,
>
> Thanks for your quick reply.
>
> Sorry, I did not clearly described the situation.
>
> I try again....
>
> Up till now, I have create Client-IP Classes to be able to enable 
> banning client for connecting too frequently with the Ban-rule 
> ClientConnectRates for some Client-IP's and to turn banning completely 
> off for the other Client-IP's.
>
> But now I would like to turn on banning for ALL Client-IP's , but 
> differentiate in the limit of the ClientConnectRate for specific 
> Client-IP's.
> So for Client-IP's that should connect frequently, I set the max. 
> ClientConnectRate to 10 per minute.
> For more frequently connecting clients, I set the max. 
> ClientConnectRate to 20 per minute.
> And for the rest of the Clients, I frequently, I set the max. 
> ClientConnectRate to 5 per minute.
>
> I create the next configuration in de Server Config:
>
> <IfModule mod_dso.c>
>         LoadModule                      mod_sql.c
>         LoadModule                      mod_sql_sqlite.c
>         LoadModule                      mod_sftp.c
>         LoadModule                      mod_auth_otp.c
>         LoadModule                      mod_ctrls_admin.c
>         LoadModule                      mod_quotatab.c
>         LoadModule                      mod_quotatab_file.c
>         LoadModule                      mod_ban.c
>         #ProFTPD v1.3.7rc4v7 compiled with DSO-module mod_ifsession
>         LoadModule                      mod_ifsession.c
> </IfModule mod_dso.c>
>
> .......
>
> <Class freq_conns>
>         From 1.2.3.4       # A test server  1
> </Class>
>
> <Class morefreq_conns>
>         From 5.6.7.8       # a Test server 2
> </Class>
>
> <IfModule mod_ban.c>
>         BanEngine               on
>         BanLog /export/org/proftpd/log/proftpd_ban.log
>         BanTable /export/org/proftpd/etc/proftpd_ban.tab
>
>         # Allow the FTP admin to manually add/remove bans
>         BanControlsACLs         all allow user root,hpprgaaj,proftpd
>         # If the same client reaches the MaxLoginAttempts limit 10 times
>         # within 1 minutes, automatically add a ban for that client that
>         # will expire after two hours.
>         #
>         BanOnEvent MaxLoginAttempts 2/00:05:00 01:00:00 "You are 
> banned out for 1 hour"
>         BanOnEvent RootLogin 1/00:01:00 02:00:00 "Stop connecting with 
> root"
>         BanOnEvent mod_auth.root-login 1/00:01:00 02:00:00 "Stop 
> connecting with root"
>
>         # Define that a banned client host in one VirtualHost is also 
> banned in the other VirtualHost.
>         BanOptions              MatchAnyServer
>
>         <IfClass freq_conns>
>                 # Set a specific ClientConnectRate for Client 
> IP-classes that normally connect frequently
>                 # or that are unknown users/client-IP's.
>                 BanOnEvent ClientConnectRate 10/00:01:00 02:00:00 
> "Stop connecting frequently"
>         </IfClass>
>
>         <IfClass morefreq_conns>
>                 # Set a specific ClientConnectRate for Client 
> IP-classes that normally connect very frequently
>                 BanOnEvent ClientConnectRate 20/00:01:00 02:00:00 
> "Stop connecting frequently"
>         </IfClass>
>
>         <IfClass !freq_conns AND !morefreq_conns>
>                 # Set a specific ClientConnectRate for all other  
> Client IP's
>                 BanOnEvent ClientConnectRate 5/00:01:00 02:00:00 "Stop 
> connecting frequently"
>         </IfClass>
> </IfModule>
>
> However, this configuration does not work as expected:
>
> 1) It looks like that only the first occurence of the 
> ClientConnectRate in the configuration is set, regardless of the Class 
> for which it is meant.
>      So, there was set a ban for the Client of Class "morefreq_conns" 
> because of more than 10 connections/min. although in the config I 
> specified a ClientConnectRate limit of 20/min.
>      The Client of Class "freq_conns" will be banned at the 
> ClientConnectRate of 10/min which is right.
>      However, for the Class "morefreq_conns", I specified a limit of 
> ClientConnectRate of 20/min - not 10/min.
>      And so for the Class "freq_conns", the same limit was set : 10/min.
>      You can see that as well with ftpdctl -s $CTRL_SOCK ban info -v -e
>     ftpdctl: Banned Hosts:
>     ftpdctl:   5.6.7.8
> ftpdctl: Reason: ClientConnectRate autoban at Mon Jun 21 21:10:28 2021
> ftpdctl: Expires: Mon Jun 21 23:10:28 2021 (in 7128 seconds)
> ftpdctl: <VirtualHost>: ProFTPD RHEL Test Dropserver-SFTP 
> (<dropserver-IP>#22)
> ftpdctl:
> ftpdctl: Ban Events:
> ftpdctl: Event: ClientConnectRate
> ftpdctl: Source: 1.2.3.4
> ftpdctl: Occurrences: 8/*10*
> ftpdctl: Entry Expires: 21 seconds
> ftpdctl: <VirtualHost>: ProFTPD RHEL Test Dropserver-SFTP 
> (10.52.129.70#22)
>
>    Didn't I configure ProFTPD not right ?
> Why is only the first Class for all Clients matched ?
>
> 2) In which ProFTPD log can I find the Class that ProFTPD daemon has 
> defined for a connected client ?
>
> 3) Strange is that while the SFTP-connections are banned, the clients 
> can connect with FTP to the same dropserver IP without problems.
>    However, I specified "BanOptions MatchAnyServer".
>    What do I do wrong ?
>
> All comments and recommendations are appreciated.
>
> Thanks in advance,
>
> With regards,
>
> Pieter de Gaaij
>
> On 19 Jun 2021 03:45, TJ Saunders wrote:
>>> Question: could it be made possible to configure different BanOnEvent
>>> ClientConnectRate rules for different Classes ?
>>>
>>> Lets say:
>>>
>>> <Class manyconnects>
>>>           From xxx.yyyy.zzzz.cccc
>>> </Class>
>>>
>>> <Class lessconnects>
>>>           From xxx.yyyy.zzzz.cccc
>>> </Class>
>> This should work -- assuming your different classes use different IP ranges, so that a given client only matches one of the defined classes.  Your example above uses the same IP ranges/DNS names, so it's hard to tell if that is what you are actually using.
>>
>> When a client connect, you should see the matching class found for it, if any, in the ProFTPD logs.
>>
>>> I think, now only the first rule is configured.
>> What behavior are you observing, to indicate that perhaps only the first class is being matched, perhaps unexpectedly?
>>
>> Cheers,
>> TJ
>>
>>
>> _______________________________________________
>> ProFTPD Users List<[email protected]>
>> Unsubscribe problems?
>> http://www.proftpd.org/list-unsub.html

_______________________________________________
ProFTPD Users List   <[email protected]>
Unsubscribe problems?
http://www.proftpd.org/list-unsub.html