Aldaviva / Fail2Ban4Win

🧱 Ban subnets using Windows Firewall rules after they make enough incorrect login attempts, as indicated by Windows Event Log records.
Apache License 2.0
42 stars 6 forks source link

Asynchronously clear existing firewall rules during startup to avoid service start timeouts #1

Closed Aldaviva closed 3 years ago

Aldaviva commented 3 years ago

While the service is starting, it deletes existing firewall rules that it previously created (filtered by Group; it doesn't delete any other rules created by other tools, Windows, or the user). It does this because otherwise the rules would never be deleted when the corresponding ban expired.

This runs in the constructor of the BanManagerImpl. The WindowsService.Start() method depends on this, so it blocks that method from finishing until all rules have been deleted. If there were a lot of rules to delete (there can be hundreds), this makes that method take a while to run. This results in the service taking a long time to start, as seen by how long it takes for net start Fail2Ban4Win to return, or for the progress bar to disappear when starting it from services.msc.

To solve this, we can start a new asynchronous Task in the constructor instead of running the blocking calls synchronously, so the constructor can finish and the rule deletion will finish at some point in the future, and the service can start and begin processing Event Log records.

To avoid overlap with rule creation, the rule deletion Task can signal a ManualResetEventSlim semaphore object or something, and rule creation can WaitOne() on that semaphore, which will only block if the initial deletion hasn't completed.

Aldaviva commented 3 years ago

Service startup will now proceed without blocking on deleting existing firewall rules, which will happen asynchronously. New ban creation will wait for this initial deletion phase to be over before adding new rules to the firewall.