Search code examples
symfonysecuritybrute-forcesymfony-security

Auto block/ban brute force scanners in Symfony


I am running a web page based on Symfony 2.7. The page uses the FOSUserBundle for user management and authentication.

I can observe in the log files, that the page is "attacked" quite often by brute force scanners.

There are two types of scans:

  1. Searching for known vulnerabilities, e.g. WordPress files, etc. which result in HTTP 404 responses
  2. Login attempts with default user credentials

I have been using WordPress before. There exist quite a lot of plugins and tools to automatically recognize and handle such attacks: If the 404 request or denied login attempts reaches a certain threshold, the user/ip is automatically blocked for some time. Usually after a few minutes the user/ip is automatically removed from the block list.

I have not been able to find such a solution for Symfony. Is there any bundle that integrates these functions into Symfony?

Of course it would not be too difficult to implement this functionally on my own. But it makes no sense to re-invent something that is already out there.


Solution

  • If you want to block malicious IP's, you should really look into fail2ban. This blogs explains it perfectly:

    Creating the Authentication Failure Handler

    <?php
    
    namespace Your\ExampleBundle\EventHandler;
    
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Security\Core\Exception\AuthenticationException;
    use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
    
    class AuthenticationFailureHandler extends DefaultAuthenticationFailureHandler
    {
        public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
        {
            if (null !== $this->logger && null !== $request->getClientIp()) {
                $this->logger->error(sprintf('Authentication failure for IP: %s', $request->getClientIp()));
            }
    
            return parent::onAuthenticationFailure($request, $exception);
        }
    }
    

    Add it to your configuration:

    services:
        your.examplebundle.authenticationfailurehandler:
            class: Your\ExampleBundle\EventHandler\AuthenticationFailureHandler
            arguments: ["@http_kernel", "@security.http_utils", {}, "@logger"]
            tags:
                - { name: 'monolog.logger', channel: 'security' }
    
    # app/config/security.yml
        firewalls:
            main:
                pattern: ^/
                form_login:
                    provider: fos_userbundle
                    csrf_provider: form.csrf_provider
                    failure_handler: your.examplebundle.authenticationfailurehandler
                logout:       true
                anonymous:    true
    

    Creating a custom fail2ban filter for Symfony2

    To create a new filter for fail2ban, we'll create a file in /etc/fail2ban/filter.d/symfony.conf with the following contents:

    [Definition]
    failregex = Authentication\sfailure\sfor\sIP:\s<HOST>\s
    

    That was easy, right? We should create a jail in /etc/fail2ban/jail.local which uses our new filter. The definition for this jail will depend on your configuration, but a basic one could look like this:

    [symfony]
    enabled   = true
    filter    = symfony
    logpath   = /var/www/my-project/app/logs/prod.log
    port      = http,https
    bantime   = 600
    banaction = iptables-multiport
    maxretry  = 3