@@ -36,7 +36,9 @@ internal static GenericIPBlockingTask FromConfiguration(IPersistentTaskConfigura
3636
3737 #region private members
3838
39+ private readonly object _syncObject = new object ( ) ;
3940 private readonly Dictionary < IPAddress , DateTime > _blockedIPsToDate = new Dictionary < IPAddress , DateTime > ( ) ;
41+ private readonly Dictionary < IPAddress , DateTime > _forgetIPsToDate = new Dictionary < IPAddress , DateTime > ( ) ;
4042 private readonly Dictionary < IPAddress , int > _bannedCount = new Dictionary < IPAddress , int > ( ) ;
4143 private readonly ILogger _logger ;
4244
@@ -64,40 +66,51 @@ internal GenericIPBlockingTask(ILogger logger)
6466 #region public operations
6567 public override List < IPAddress > GetTempBanVictims ( )
6668 {
67- List < IPAddress > ipsToRemove = new List < IPAddress > ( ) ;
68- List < IPAddress > ipsToBlock = new List < IPAddress > ( ) ;
69-
70- //also remove IPS from ban list when they have been blocked "long enough"
71- foreach ( KeyValuePair < IPAddress , DateTime > kvp in _blockedIPsToDate )
69+ lock ( _syncObject )
7270 {
73- if ( kvp . Value . Add ( new TimeSpan ( 0 , 0 , LockTime ) ) < System . DateTime . Now )
74- {
75- ipsToRemove . Add ( kvp . Key ) ;
76- }
77- else
71+ List < IPAddress > ipsToRemove = new List < IPAddress > ( ) ;
72+ List < IPAddress > ipsToBlock = new List < IPAddress > ( ) ;
73+
74+ //also remove IPS from ban list when they have been blocked "long enough"
75+ foreach ( KeyValuePair < IPAddress , DateTime > kvp in _blockedIPsToDate )
7876 {
79- ipsToBlock . Add ( kvp . Key ) ;
77+ if ( kvp . Value . Add ( new TimeSpan ( 0 , 0 , LockTime ) ) < DateTime . Now )
78+ {
79+ ipsToRemove . Add ( kvp . Key ) ;
80+ }
81+ else
82+ {
83+ ipsToBlock . Add ( kvp . Key ) ;
84+ }
8085 }
81- }
8286
83- foreach ( IPAddress ipToRemove in ipsToRemove )
84- _blockedIPsToDate . Remove ( ipToRemove ) ;
87+ //also remove forgotten IPs when its been a while
88+ List < IPAddress > removeFromForgottenList = _forgetIPsToDate . Where ( p => DateTime . Now . AddHours ( - 1 ) > p . Value ) . Select ( p=> p . Key ) . ToList ( ) ;
89+ foreach ( var ip in removeFromForgottenList )
90+ removeFromForgottenList . Remove ( ip ) ;
91+
92+ foreach ( IPAddress ipToRemove in ipsToRemove )
93+ _blockedIPsToDate . Remove ( ipToRemove ) ;
8594
86- return ipsToBlock ;
95+ return ipsToBlock ;
96+ }
8797 }
8898
8999 public override List < IPAddress > GetPermaBanVictims ( )
90100 {
91- List < IPAddress > permaList = new List < IPAddress > ( ) ;
92- foreach ( KeyValuePair < IPAddress , int > kvp in _bannedCount . Where ( p=> p . Value >= PermaBanCount ) )
101+ lock ( _syncObject )
93102 {
94- permaList . Add ( kvp . Key ) ;
95- _logger . Dump ( $ "Permanently banned { kvp . Value } (strike count was over { PermaBanCount } ) ", SeverityLevel . Info ) ;
96- }
97- foreach ( IPAddress ip in permaList )
98- _bannedCount . Remove ( ip ) ;
103+ List < IPAddress > permaList = new List < IPAddress > ( ) ;
104+ foreach ( KeyValuePair < IPAddress , int > kvp in _bannedCount . Where ( p => p . Value >= PermaBanCount ) )
105+ {
106+ permaList . Add ( kvp . Key ) ;
107+ _logger . Dump ( $ "Permanently banned { kvp . Value } (strike count was over { PermaBanCount } ) ", SeverityLevel . Info ) ;
108+ }
109+ foreach ( IPAddress ip in permaList )
110+ _bannedCount . Remove ( ip ) ;
99111
100- return permaList ;
112+ return permaList ;
113+ }
101114 }
102115
103116 protected override void OnComputeEvents ( List < ExtractedEventRecord > events )
@@ -133,32 +146,55 @@ protected override void OnComputeEvents(List<ExtractedEventRecord> events)
133146 {
134147 if ( m . Groups . Count == 2 && IPAddress . TryParse ( m . Groups [ 1 ] . Value , out IPAddress ipAddress ) )
135148 {
149+ if ( _forgetIPsToDate . ContainsKey ( ipAddress ) && _forgetIPsToDate [ ipAddress ] > e . TimeCreated )
150+ {
151+ _logger . Dump ( $ "{ Name } : found { ipAddress } but ignored it (was recently removed from autoban list)", SeverityLevel . Info ) ;
152+ continue ;
153+ }
136154
137155 if ( ! sourceToCount . ContainsKey ( ipAddress ) )
138156 sourceToCount . Add ( ipAddress , 1 ) ;
139157 else
140158 sourceToCount [ ipAddress ] ++ ;
141159
142- _logger . Dump ( $ "{ Name } : found { ipAddress } , trigger count is { sourceToCount [ ipAddress ] } ", SeverityLevel . Info ) ;
160+ _logger . Dump ( $ "{ Name } : found { ipAddress } , trigger count is { sourceToCount [ ipAddress ] } ", SeverityLevel . Verbose ) ;
143161 }
144162 }
145163 }
146164
147- foreach ( KeyValuePair < IPAddress , int > kvp in sourceToCount )
165+ lock ( _syncObject )
148166 {
149- if ( kvp . Value >= TriggerCount && ! _blockedIPsToDate . ContainsKey ( kvp . Key ) )
167+ foreach ( KeyValuePair < IPAddress , int > kvp in sourceToCount )
150168 {
151- _blockedIPsToDate . Add ( kvp . Key , DateTime . Now ) ;
152- if ( ! _bannedCount . ContainsKey ( kvp . Key ) )
153- _bannedCount [ kvp . Key ] = 1 ;
154- else
155- _bannedCount [ kvp . Key ] += 1 ;
169+ if ( kvp . Value >= TriggerCount && ! _blockedIPsToDate . ContainsKey ( kvp . Key ) )
170+ {
171+ _blockedIPsToDate . Add ( kvp . Key , DateTime . Now ) ;
172+ if ( ! _bannedCount . ContainsKey ( kvp . Key ) )
173+ _bannedCount [ kvp . Key ] = 1 ;
174+ else
175+ _bannedCount [ kvp . Key ] += 1 ;
156176
157- _logger . Dump ( $ "Temporarily banning { kvp . Key } , this is strike { _bannedCount [ kvp . Key ] } ", SeverityLevel . Info ) ;
177+ _logger . Dump ( $ "Temporarily banning { kvp . Key } , this is strike { _bannedCount [ kvp . Key ] } ", SeverityLevel . Info ) ;
178+ }
158179 }
159180 }
160181 }
161182
183+ public override void Forget ( IPAddress address )
184+ {
185+ lock ( _syncObject )
186+ {
187+ _blockedIPsToDate . Remove ( address ) ;
188+
189+ if ( ! _forgetIPsToDate . ContainsKey ( address ) )
190+ _forgetIPsToDate . Add ( address , DateTime . Now ) ;
191+ else
192+ _forgetIPsToDate [ address ] = DateTime . Now ;
193+
194+ _bannedCount . Remove ( address ) ;
195+ }
196+ }
197+
162198 #endregion
163199 }
164200}
0 commit comments