How do you protect Cockpit against Brute Force Attacks?

I know, brute force protection is no simple task and everyone might need some different implementation. But I think Cockpit should have a basic protection against brute force attacks in the core or as an addon.

There is fail2ban out there, but that is no real option on a shared host without sudo rights and by default Cockpit has no log files.

I see two things, that need protection:

  1. REST API keys
  2. Login page

1. REST API keys

They are very hard to guess, so the login page might be the better target. Nevertheless, it’s possible to send thousands or millions of requests to e. g. /api/cockpit/listUsers until the server sends a 200. Blocking IPs after x wrong attempts would be useful.

2. Login page

Let’s assume, a user name or an email address is known already, because

  • they are used in the web application or
  • the admin email address is the same as the one in the imprint
  • etc…

Now we could start a dictionary attack against /auth/check.

Adding a delay after x failed login attempts would be relatively easy to implement:

// $user = 'user'
$this->on('cockpit.authentication.failed', function($user = '') {

    // log (in log file or in database):
    // * user name, IP, time
    // * $count of failed attempts during date range
    // set a random $delay
    if ($count > 10) {
        // send an email to admin
        // set user as inactive
    }

});

// $user = ['user' => 'user', ...]
$this->on('cockpit.authentication.success', function(&$user) {

    // get database entry or parse log file
    if (time() < $delay) {
        $this->stop();
    }

});

But this could be used as an exploit to set users to inactive…
See also: https://www.owasp.org/index.php/Blocking_Brute_Force_Attacks

So - how do you protect cockpit against brute force attacks?

Should Cockpit have a basic brute force protection by default or via addon? Or should the users decide about their own, unique implementation?

I’m very interested in best practices

  • for dedicated hosts with fail2ban,
  • for shared hosts with a lot of options like cronjobs, Python etc.,
  • and also for annoying shared hosts (e.g. without SSH access)

For the authentication, I think a basic lock mechanism based on the number of attempts (configurable) should be in Cockpit. For more advanced cases like banning ip addresses think would be better via an addon.

Are there any plans to bring brute force protection for the login page into the core?
@raffaelj Did you implement it like described above and could help me to do the same. I don’t know in which file I could put the hooks for ‘cockpit.authentication.failed’ and ‘cockpit.authentication.success’.

@rttmax I didn’t implement it yet, because I had and have some other jobs to do. It is on my to-do-list, but I don’t know, when I find some time.

You can add the code to a custom bootstrap.php in /config or you could write an addon.

I started a very simple project that provides the ability of locking users after n failed login attempts - https://github.com/pauloamgomes/CockpitCMS-UserFlood

I plan to have more advanced features like blocking based on ip address and a specific time duration but for now think it does the job.

1 Like