Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sf2Security Bundle Laravel Package

loamok/sf2security-bundle

Loamok SF2SecurityBundle is a Symfony 2 security bundle that integrates authentication and access-control services, helping PHP applications manage users, roles, and protected routes through configurable Symfony security settings.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the honest orientation: loamok/sf2security-bundle is a Symfony 2 bundle for wiring the Symfony Security Component to a host-level fail2ban daemon. It is not installable or usable inside a Laravel application. There is no service provider, no facade, no middleware, no config integration — its entry point is a Symfony Bundle class registered in app/AppKernel::registerBundles() and its config lives in app/config/config.yml. If you are a Laravel dev looking at this package, the realistic "getting started" is: do not composer require it. What you can actually harvest day-to-day is the pattern — a stable, parseable authentication-failure log line that a fail2ban filter can match — and re-implement it natively in ~30 lines of Laravel.

Where to look first (reading, not installing): clone the repo and read, in order:

  1. composer.json — confirm the Symfony 2.x constraint and PHP version; this tells you instantly it will not co-exist with Laravel's dependency tree.
  2. The bundle class and DependencyInjection/ config — this shows what services it registers (a security event listener/subscriber is the usual suspect).
  3. Any Resources/config/*.xml/.yml — this reveals the actual integration point: it subscribes to security.authentication.failure (Symfony's auth-failure event) and writes a log record.
  4. Any Resources/config/ fail2ban filter sample — the regex and log-line shape are the only reusable artifact.

First use case (Laravel-native equivalent): log failed login attempts to a dedicated channel in a format a fail2ban filter can match, then let ops create the jail. Minimal implementation:

// config/logging.php — dedicated channel
'channels' => [
    'auth_failures' => [
        'driver' => 'daily',
        'path'   => storage_path('logs/auth-failures.log'),
        'days'   => 14,
    ],
],
// app/Listeners/LogFailedLogin.php — listen for Auth\Events\Failed
use Illuminate\Auth\Events\Failed;
use Illuminate\Support\Facades\Log;

class LogFailedLogin
{
    public function handle(Failed $event): void
    {
        Log::channel('auth_failures')->warning(
            'AUTH_FAILURE ip={ip} user={user} route={route} ua="{ua}"',
            [
                'ip'     => request()->ip(),
                'user'   => $event->credentials['email'] ?? 'unknown',
                'route'  => request()->path(),
                'ua'     => substr((string) request()->userAgent(), 0, 200),
            ]
        );
    }
}
# /etc/fail2ban/filter.d/laravel-auth.conf
[Definition]
failregex = ^.*AUTH_FAILURE ip=<HOST> .*$
ignoreregex =

The whole "leverage the package" story for a Laravel dev is this: use the log-line contract as a design reference, implement the logging natively, and hand ban enforcement to platform/SRE.

Implementation Patterns

Pattern 1 — Port the listener, not the bundle. The bundle's functional core is an event listener that fires on authentication failure. In Laravel, the equivalent event is Illuminate\Auth\Events\Failed (dispatched by the AuthenticatesUsers/LogoutOtherDevices flow in AuthController or by Illuminate\Auth\SessionGuard::attempt() on failure). Register the listener in EventServiceProvider. Bind it with care: Failed also fires on validation-time attempts, so if you're using Fortify/Breeze, ensure you're listening in one place, not overlapping.

Pattern 2 — Structured log format with a stable schema. The reusable idea from the Symfony bundle is a single-line, whitespace-delimited, key=value record — trivially regex-able by fail2ban. Do not log JSON if you want a simple <HOST> match; fail2ban's failregex uses <HOST> for the IP, and mixing JSON escaping with that regex is painful. Keep the IP early in the line, or use the __prefix_line convention in newer fail2ban versions. Include: IP, username/email (hashed if PII-sensitive), route, timestamp, and a short fingerprint of the user agent.

Pattern 3 — Proxy-aware IP resolution. A fail2ban ban is only as good as the IP you log. In Laravel, request()->ip() respects TrustProxies middleware; configure it correctly so X-Forwarded-For is trusted only from your known proxy/LB ranges. Do this before the first production deployment of the jail; getting IP wrong is the #1 cause of either banning the LB or banning the CDN.

Pattern 4 — Throttle first, ban second. In parallel with the log line, apply Laravel's RateLimiter / ThrottleRequests on the login route (RateLimiter::for('login', ...)). This provides immediate, app-level defense with a shared store (Redis in multi-node), while fail2ban provides the firewall-level deterrent. These are complements; do both. Symfony's own login_throttling is what superseded the bundle's approach in Symfony 4+, and its Laravel analogue is RateLimiter.

Pattern 5 — Centralised logs if you're distributed. fail2ban reads host log files. On Kubernetes/ECS/autoscaled hosts, either (a) sidecar your Laravel app with a fail2ban container reading a shared log volume, or (b) forward logs (Vector/Fluent Bit) to a log store and run fail2ban on the collector. Neither the Symfony bundle nor any drop-in solves this — it's an ops pattern.

Pattern 6 — Integrate with laravel.log rotation. Use a dedicated channel (as above) with daily rotation so the fail2ban filter's file path is stable and doesn't need to parse a general-purpose log. Configure postrotate/logrotate to send SIGUSR1 to fail2ban so it picks up rotation. A common failure: fail2ban reads a file handle to an inode that logrotate has renamed, and silently misses events.

Gotchas and Tips

  • Composer incompatibility is real, not cosmetic. Adding Symfony 2 components to a Laravel 10/11 project will attempt to downgrade psr/*, symfony/*, and possibly block installation entirely depending on your constraint set. Do not try to force it. There is no bridge package and no maintained fork (zero dependents, archived repo, five stars).
  • Auth\Events\Failed credentials are sensitive. The Failed event exposes the attempted credentials array. Log only a hash or partial of the email (hash('sha256', $email) truncated), never the password, never the full credentials payload. Sanitise user agents; attackers control them.
  • Fail2ban is a host concern; keep enforcement out of the app. The bundle's real design flaw (for modern use) is coupling the app to a host daemon. Keep the boundary: app emits logs, platform owns bans. This is also more portable to a WAF/CrowdSec later if you scale out.
  • <HOST> matching depends on line shape. Fail2ban's filter regex is brittle. Test with fail2ban-regex /path/to/auth-failures.log /etc/fail2ban/filter.d/yourfilter.conf on real log samples before trusting the jail. An unmatched filter silently provides zero protection.
  • False positives and self-ban are the big operational risk. Banning on a single failure, or matching too broad a pattern (e.g. any WARNING), will lock out legitimate users — often support staff behind shared office IPs. Use maxretry, findtime, and bantime generously; test with maxretry=5, findtime=10m, bantime=1h before relaxing/tightening. Consider an ignoreip list for internal networks, the LB, and your on-call.
  • IP behind CDN/LB — again. If you sit behind Cloudflare/ALB and trust proxies wrongly, fail2ban bans the CDN edge and you take down all traffic; if you trust too little, you log the LB IP and ban every user. Configure TrustProxies with explicit CIDR ranges.
  • LGPL-3.0 is not a trivial licensing concern. You cannot vendor or inline this code and redistribute without triggering relinking obligations and legal review. If you're only reading the code to copy a pattern (log format, event hook), you're generally fine — but if you copy substantial expression, route it through legal.
  • If inherited in a legacy Symfony 2 app: don't upgrade the bundle; pin the version, keep the filter files, and schedule migration to Symfony's native login throttling. The bundle will never receive a security patch.
  • Debugging tip: when log lines aren't reaching fail2ban, check in this order — (1) is storage/logs/auth-failures.log actually being written? (2) does the file have the permissions fail2ban needs (fail2ban often runs as root or a dedicated user)? (3) does fail2ban-client status yourjail show the jail active and total failed incrementing? (4) tail -f the log while triggering a failed login.
  • Extension point you might want: if you need richer signal, fire your own LoginFailed domain event alongside Auth\Events\Failed and let listeners decide (log, increment metrics, trigger a notification for admins). This gives you a single seam if you later move enforcement to a WAF or CrowdSec without changing the login flow.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package