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

GUACAMOLE-990: Add extension for automatically blocking brute-force auth attempts. #758

Merged
merged 10 commits into from Aug 22, 2022

Conversation

mike-jumper
Copy link
Contributor

This change adds a new extension, "guacamole-auth-ban", which automatically tracks failed authentication attempts. After a specified limit has been reached, the IP address that is failing to authenticate is temporarily banned. This includes failures to provide valid MFA codes, etc., if Guacamole is configured to require them.

By default, addresses that repeatedly fail authentication are banned for 5 minutes (300 seconds) after 5 failed attempts, and these values can be overridden with the ban-address-duration and ban-max-invalid-attempts properties respectively.

The maximum number of addresses tracked is ~10 million by default (10485760), and this can be overridden with the ban-max-addresses property. It is intentionally not possible to remove the limit entirely, though it can be set as high as desired.

If too many authentication failures have occurred, the user failing to authenticate will see a message like:

Screenshot of automatically-blocked authentication attempt

In addition to implementing the extension itself, this change involved:

  • Modifying the firing of auth events such that they are always fired only after authentication has entirely succeeded or entirely failed.
  • Modifying handling of auth failures such that past auth tokens are removed from client-side storage after they have been determined to be invalid (they will otherwise be pointlessly resubmitted and will count toward auth failures).

…tion has absolutely succeeded or failed, including the details of any failure.

Previously, these events were fired only after the user's identity had
been determined (or failed to be determined). If we don't wait until
after the user contexts have also been successfully obtained (or failed
to be obtained), then things like MFA will not be taken into account
for auth events.
@mike-jumper mike-jumper marked this pull request as draft August 22, 2022 20:18
@mike-jumper mike-jumper marked this pull request as ready for review August 22, 2022 20:20
@mike-jumper
Copy link
Contributor Author

NOTE: This extension works by aborting authentication early by throwing a GuacamoleClientTooManyException, which immediately aborts via the following code path:

catch (GuacamoleException | RuntimeException | Error e) {
throw new GuacamoleAuthenticationProcessException("User "
+ "authentication was aborted.", authProvider, e);
}

This is naturally dependent on the order that extensions are loaded, hence naming things such that it's loaded first within the Docker image:

# Ensure guacamole-auth-ban always loads before other extensions unless
# explicitly overridden via naming or EXTENSION_PRIORITY (allowing other
# extensions to attempt authentication before guacamole-auth-ban has a chance
# to enforce any bans could allow credentials to continue to be guessed even
# after the address has been blocked via timing attacks)
ln -s /opt/guacamole/ban/guacamole-auth-*.jar "$GUACAMOLE_EXT/_guacamole-auth-ban.jar"

Loading the extension before all other auth extensions is necessary for correct behavior with respect to timing, and we'll have to document this in the manual.

If the extension is installed but not loaded first, then extensions that load earlier will be given a chance to authenticate the user before guacamole-auth-ban can abort the auth process. Even though repeated auth attempts will still be blocked, the amount of time taken until that block occurs might vary by whether the credentials provided were valid according to those other extensions, and that variance in timing might allow an attacker to determine whether their guess is correct even though full auth is temporarily blocked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants