我正在运行基于Symfony 2.7的网页。该页面使用FOSUserBundle进行用户管理和身份验证。

我可以在日志文件中看到,该页面经常被暴力扫描程序“攻击”。

扫描有两种类型:

  • 搜索已知漏洞,例如WordPress文件等导致HTTP 404响应
  • 使用默认用户凭据登录尝试

  • 我以前一直在使用WordPress。有很多插件和工具可以自动识别和处理此类攻击:如果404请求或拒绝的登录尝试达到某个阈值,则用户/ip会在一段时间内自动被阻止。通常,几分钟后,用户/ip会自动从阻止列表中删除。

    我无法为Symfony找到这样的解决方案。是否有将这些功能集成到Symfony中的捆绑包?

    当然,靠我自己实现此功能并不难。但是重新发明已经存在的东西是没有意义的。

    最佳答案

    如果要阻止恶意IP,则应真正研究fail2banThis blogs完美地说明了这一点:

    创建身份验证失败处理程序

    <?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);
        }
    }
    

    将其添加到您的配置中:
    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
    

    为Symfony2创建自定义的fail2ban过滤器

    要为fail2ban创建一个新的过滤器,我们将在/etc/fail2ban/filter.d/symfony.conf中创建一个文件,其内容如下:
    [Definition]
    failregex = Authentication\sfailure\sfor\sIP:\s<HOST>\s
    

    那很容易,对吧?我们应该在/etc/fail2ban/jail.local中使用我们的新过滤器创建一个 jail 。该 jail 的定义将取决于您的配置,但是一个基本的 jail 可能看起来像这样:
    [symfony]
    enabled   = true
    filter    = symfony
    logpath   = /var/www/my-project/app/logs/prod.log
    port      = http,https
    bantime   = 600
    banaction = iptables-multiport
    maxretry  = 3
    

    10-06 00:38