diff --git a/website/app/fail2ban-alternative/page.tsx b/website/app/fail2ban-alternative/page.tsx new file mode 100644 index 0000000..b84f86a --- /dev/null +++ b/website/app/fail2ban-alternative/page.tsx @@ -0,0 +1,293 @@ +import type { Metadata } from 'next'; +import Link from 'next/link'; +import { ArrowRight, Container, FileSearch, ShieldCheck, Timer } from 'lucide-react'; +import { getSiteUrl } from '@/lib/config'; +import { buildDocsStructuredData, toJsonLd } from '@/lib/structured-data'; + +const PAGE_PATH = '/fail2ban-alternative'; + +export const metadata: Metadata = { + title: 'Fail2ban Alternative for Containers and Web Attacks', + description: + 'Looking for a fail2ban alternative? StackdogApp keeps fail2ban-style IP bans for SSH floods and adds shipped detections for web attacks, webshells and PHP2Shell — with Docker container logs discovered automatically.', + keywords: [ + 'fail2ban alternative', + 'fail2ban vs', + 'fail2ban docker', + 'fail2ban containers', + 'fail2ban web application', + 'StackdogApp' + ], + alternates: { + canonical: PAGE_PATH + }, + openGraph: { + title: 'Fail2ban Alternative for Containers and Web Attacks — StackdogApp', + description: + 'fail2ban-style bans, shipped detections instead of per-error regex, and Docker container logs read like host logs.', + url: getSiteUrl() + PAGE_PATH + }, + twitter: { + title: 'Fail2ban Alternative for Containers and Web Attacks — StackdogApp', + description: + 'fail2ban-style bans, shipped detections instead of per-error regex, and Docker container logs read like host logs.' + } +}; + +const comparisonRows = [ + [ + 'Trigger', + 'Too many failed logins in a log line — its README describes scanning logs like /var/log/auth.log', + 'The same SSH/PAM failures, plus shipped detections: SQL injection probes, path traversal, brute force, webshell access, PHP2Shell attempts' + ], + [ + 'Configuration', + 'Per error: it reads "any log file of your choosing, for any error you wish" — each one is a jail and a filter you maintain', + 'The detections ship with the product. Thresholds are env vars (five offenses in five minutes by default)' + ], + [ + 'Log sources', + 'Host log files; out of the box sshd and Apache', + 'Host logs and Docker container logs, discovered on their own; nginx, Apache and application formats' + ], + [ + 'What it correlates', + 'One log line at a time', + 'Files and requests: a webshell is a file on disk and a request to it — StackdogApp reads both and bans whoever drives the shell' + ], + [ + 'Ban mechanics', + 'Updates system firewall rules for a configurable time', + 'iptables/nftables rules with their own marker, reconciled against the database: a crash strands neither a ban nor a phantom rule. Bans expire and release themselves' + ], + [ + 'Safety rails', + 'Configured per jail', + 'Allowlist, private and local infrastructure never banned, Docker network subnets protected automatically, per-minute cap on new bans' + ] +]; + +const differences = [ + { + icon: Container, + title: 'Containers are first-class', + body: 'Your PHP lives in containers, so its logs do too. StackdogApp discovers container logs and reads them like host files — no bind-mounting logs out of containers to satisfy a host-side daemon.' + }, + { + icon: FileSearch, + title: 'Detections, not regex maintenance', + body: 'Every new attack pattern in a fail2ban setup waits for someone to write a filter. StackdogApp ships the patterns — including the PHP2Shell crash step, where the footprint is "in Unknown on line 0", not a payload.' + }, + { + icon: Timer, + title: 'Unban is part of the design', + body: 'Bans expire and release themselves; the firewall and the database are reconciled every pass, so a restart cannot strand a block or leave a stale drop rule behind.' + }, + { + icon: ShieldCheck, + title: 'One product, not a pile of jails', + body: 'SSH floods, web attacks, webshells and PHP version exposure are one pipeline: one alert stream, one ban engine, one place to look when something happened.' + } +]; + +export default function Fail2BanAlternativePage() { + return ( +
+