Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ability to remove temp bans #47

Merged
merged 3 commits into from
Feb 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Source/EvlWatcher/EvlWatcher.WCF/IEvlWatcherService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,9 @@ public interface IEvlWatcherService
[OperationContract]
[FaultContract(typeof(ServiceFaultDTO))]
void SaveGlobalConfig(SeverityLevelDTO logLevel, int consoleBackLog, int checkInterval);

[OperationContract]
[FaultContract(typeof(ServiceFaultDTO))]
void RemoveTemporaryBan(IPAddress address);
}
}
19 changes: 16 additions & 3 deletions Source/EvlWatcher/EvlWatcher/EvlWatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,6 @@ private void Run()
}
}


//start monitoring the logs
while (true)
{
Expand Down Expand Up @@ -469,7 +468,6 @@ private void Run()

_logger.Dump($"Scanning finished in {DateTime.Now.Subtract(scanStart).TotalMilliseconds}[ms] ", SeverityLevel.Debug);


//then supply the events to the requesting tasks
foreach (string key in requiredEventTypesToLogTasks.Keys)
{
Expand Down Expand Up @@ -514,7 +512,6 @@ private void Run()

List<IPAddress> blockedIPs = ipTask.GetTempBanVictims();


_logger.Dump($"Polled {t.Name} and got {blockedIPs.Count} temporary and {_serviceconfiguration.BlacklistAddresses.Count()} permanent ban(s)", SeverityLevel.Verbose);

foreach (IPAddress blockedIP in blockedIPs)
Expand Down Expand Up @@ -611,6 +608,22 @@ public void SaveGlobalConfig(SeverityLevelDTO logLevel, int consoleBackLog, int
_serviceconfiguration.EventLogInterval = checkInterval;
}

public void RemoveTemporaryBan(IPAddress address)
{
EnsureClientPrivileges();

lock (_syncObject)
{
_logger.Dump($"Removing IP {address} from temporary ban list", SeverityLevel.Info);
foreach (var ipBlockingTask in _logTasks.Where(t => t is IPBlockingLogTask).Select(t => t as IPBlockingLogTask))
{
ipBlockingTask.Forget(address);
}
_lastPolledTempBans.Remove(address);
PushBanList();
}
}

#endregion
}
}
96 changes: 65 additions & 31 deletions Source/EvlWatcher/EvlWatcher/tasks/GenericIPBlockingTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ internal static GenericIPBlockingTask FromConfiguration(IPersistentTaskConfigura

#region private members

private readonly object _syncObject = new object();
private readonly Dictionary<IPAddress, DateTime> _blockedIPsToDate = new Dictionary<IPAddress, DateTime>();
private readonly Dictionary<IPAddress, DateTime> _forgetIPsToDate = new Dictionary<IPAddress, DateTime>();
private readonly Dictionary<IPAddress, int> _bannedCount = new Dictionary<IPAddress, int>();
private readonly ILogger _logger;

Expand Down Expand Up @@ -64,40 +66,51 @@ internal GenericIPBlockingTask(ILogger logger)
#region public operations
public override List<IPAddress> GetTempBanVictims()
{
List<IPAddress> ipsToRemove = new List<IPAddress>();
List<IPAddress> ipsToBlock = new List<IPAddress>();

//also remove IPS from ban list when they have been blocked "long enough"
foreach (KeyValuePair<IPAddress, DateTime> kvp in _blockedIPsToDate)
lock (_syncObject)
{
if (kvp.Value.Add(new TimeSpan(0, 0, LockTime)) < System.DateTime.Now)
{
ipsToRemove.Add(kvp.Key);
}
else
List<IPAddress> ipsToRemove = new List<IPAddress>();
List<IPAddress> ipsToBlock = new List<IPAddress>();

//also remove IPS from ban list when they have been blocked "long enough"
foreach (KeyValuePair<IPAddress, DateTime> kvp in _blockedIPsToDate)
{
ipsToBlock.Add(kvp.Key);
if (kvp.Value.Add(new TimeSpan(0, 0, LockTime)) < DateTime.Now)
{
ipsToRemove.Add(kvp.Key);
}
else
{
ipsToBlock.Add(kvp.Key);
}
}
}

foreach (IPAddress ipToRemove in ipsToRemove)
_blockedIPsToDate.Remove(ipToRemove);
//also remove forgotten IPs when its been a while
List<IPAddress> removeFromForgottenList = _forgetIPsToDate.Where(p => DateTime.Now.AddHours(-1) > p.Value).Select(p=>p.Key).ToList();
foreach (var ip in removeFromForgottenList)
removeFromForgottenList.Remove(ip);

foreach (IPAddress ipToRemove in ipsToRemove)
_blockedIPsToDate.Remove(ipToRemove);

return ipsToBlock;
return ipsToBlock;
}
}

public override List<IPAddress> GetPermaBanVictims()
{
List<IPAddress> permaList = new List<IPAddress>();
foreach (KeyValuePair<IPAddress, int> kvp in _bannedCount.Where(p=>p.Value>=PermaBanCount))
lock (_syncObject)
{
permaList.Add(kvp.Key);
_logger.Dump($"Permanently banned {kvp.Value} (strike count was over {PermaBanCount}) ", SeverityLevel.Info);
}
foreach (IPAddress ip in permaList)
_bannedCount.Remove(ip);
List<IPAddress> permaList = new List<IPAddress>();
foreach (KeyValuePair<IPAddress, int> kvp in _bannedCount.Where(p => p.Value >= PermaBanCount))
{
permaList.Add(kvp.Key);
_logger.Dump($"Permanently banned {kvp.Value} (strike count was over {PermaBanCount}) ", SeverityLevel.Info);
}
foreach (IPAddress ip in permaList)
_bannedCount.Remove(ip);

return permaList;
return permaList;
}
}

protected override void OnComputeEvents(List<ExtractedEventRecord> events)
Expand Down Expand Up @@ -133,6 +146,11 @@ protected override void OnComputeEvents(List<ExtractedEventRecord> events)
{
if (m.Groups.Count == 2 && IPAddress.TryParse(m.Groups[1].Value, out IPAddress ipAddress))
{
if (_forgetIPsToDate.ContainsKey(ipAddress) && _forgetIPsToDate[ipAddress] > e.TimeCreated )
{
_logger.Dump($"{Name}: found {ipAddress} but ignored it (was recently removed from autoban list)", SeverityLevel.Info);
continue;
}

if (!sourceToCount.ContainsKey(ipAddress))
sourceToCount.Add(ipAddress, 1);
Expand All @@ -144,21 +162,37 @@ protected override void OnComputeEvents(List<ExtractedEventRecord> events)
}
}

foreach (KeyValuePair<IPAddress, int> kvp in sourceToCount)
lock (_syncObject)
{
if (kvp.Value >= TriggerCount && !_blockedIPsToDate.ContainsKey(kvp.Key))
foreach (KeyValuePair<IPAddress, int> kvp in sourceToCount)
{
_blockedIPsToDate.Add(kvp.Key, DateTime.Now);
if (!_bannedCount.ContainsKey(kvp.Key))
_bannedCount[kvp.Key] = 1;
else
_bannedCount[kvp.Key] += 1;
if (kvp.Value >= TriggerCount && !_blockedIPsToDate.ContainsKey(kvp.Key))
{
_blockedIPsToDate.Add(kvp.Key, DateTime.Now);
if (!_bannedCount.ContainsKey(kvp.Key))
_bannedCount[kvp.Key] = 1;
else
_bannedCount[kvp.Key] += 1;

_logger.Dump($"Temporarily banning {kvp.Key}, this is strike {_bannedCount[kvp.Key]}", SeverityLevel.Info);
_logger.Dump($"Temporarily banning {kvp.Key}, this is strike {_bannedCount[kvp.Key]}", SeverityLevel.Info);
}
}
}
}

public override void Forget(IPAddress address)
{
lock (_syncObject)
{
_blockedIPsToDate.Remove(address);

if (!_forgetIPsToDate.ContainsKey(address))
_forgetIPsToDate.Add(address, DateTime.Now);

_bannedCount.Remove(address);
}
}

#endregion
}
}
2 changes: 2 additions & 0 deletions Source/EvlWatcher/EvlWatcher/tasks/IPBlockingLogTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ public abstract class IPBlockingLogTask : LogTask
{
public abstract List<IPAddress> GetTempBanVictims();
public abstract List<IPAddress> GetPermaBanVictims();

public abstract void Forget(IPAddress address);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ internal void SaveGlobalConfig(SeverityLevelDTO logLevel, int consoleBackLog, in
Service.SaveGlobalConfig(logLevel, consoleBackLog, checkInterval);
}

internal void RemoveTemporaryBan(IPAddress selectedTemporaryIP)
{
Service.RemoveTemporaryBan(selectedTemporaryIP);
}

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,15 @@
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Grid.Column="1" Command="{Binding MoveTemporaryToPermaCommand}" Margin="5,5,5,5" Grid.Row="2" IsEnabled="{Binding IsServiceResponding}" ToolTip="Move to permanent ban list">
<Button Grid.Column="1" Margin="5,5,5,5" Command="{Binding RemoveTemporaryBanCommand}" IsEnabled="{Binding IsServiceResponding}" ToolTip="Remove the selected IP from the temporary ban list">
<Image Source="pack://application:,,,/Resources/close_32.ico"></Image>
</Button>
<Button Grid.Column="2" Command="{Binding MoveTemporaryToPermaCommand}" Margin="5,5,5,5" Grid.Row="2" IsEnabled="{Binding IsServiceResponding}" ToolTip="Move to permanent ban list">
<Image Source="pack://application:,,,/Resources/lock_32.ico"></Image>
</Button>
<Button Grid.Column="2" Command="{Binding MoveTemporaryToWhiteListCommand}" Margin="5,5,5,5" Grid.Row="2" IsEnabled="{Binding IsServiceResponding}" ToolTip="Whitelist this IP">
<Button Grid.Column="3" Command="{Binding MoveTemporaryToWhiteListCommand}" Margin="5,5,5,5" Grid.Row="2" IsEnabled="{Binding IsServiceResponding}" ToolTip="Whitelist this IP">
<Image Source="pack://application:,,,/Resources/lock_open_32.ico"></Image>
</Button>
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,16 @@ public IList<string> AvailableTaskNames
}
}


public ICommand RemoveTemporaryBanCommand
{
get
{
return new RelayCommand(p =>
{ _model.RemoveTemporaryBan(SelectedTemporaryIP); }, p => SelectedTemporaryIP != null && IsServiceResponding );
}
}

public ICommand AddPermaBanCommand
{
get
Expand Down