mirror of
https://github.com/myronblair/novacpx
synced 2026-06-30 17:50:41 -05:00
Fail2Ban whitelist management + auth failure logging
- firewall.php: auto-detect server IPs (loopback, all interface IPs, private /24 subnets) for Fail2Ban ignoreip; f2b-ignoreip-list/add/ remove/reset actions; write to jail.local directly (www-data owns it); f2b_set_ignoreip() reloads fail2ban after every change - auth.php: log failed logins to /var/log/novacpx/access.log in format fail2ban filters expect — "FAILED LOGIN from <IP> [portal]" - deploy/fail2ban/: filter.d conf files for all 4 NovaCPX jails - install.sh: auto-detect local IPs → ignoreip in jail.local; install filter files; create access.log (www-data:www-data 664) - admin.js: Fail2Ban Whitelist section in firewall page — chip list with add/remove/reset; loopback shown with lock icon and non-removable Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,16 @@ match ($action) {
|
||||
if (!$username || !$password) Response::error('Username and password required');
|
||||
$auth = Auth::getInstance();
|
||||
$token = $auth->attempt($username, $password);
|
||||
if (!$token) Response::error('Invalid credentials', 401);
|
||||
if (!$token) {
|
||||
// Log failure for Fail2Ban to detect
|
||||
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
||||
$port = (int)($_SERVER['SERVER_PORT'] ?? 0);
|
||||
$portal = $port === PORT_ADMIN ? 'admin' : ($port === PORT_RESELLER ? 'reseller' : ($port === PORT_WEBMAIL ? 'webmail' : 'user'));
|
||||
$logLine = date('Y-m-d H:i:s') . " FAILED LOGIN from {$ip} [{$portal}] user:{$username}\n";
|
||||
@file_put_contents('/var/log/novacpx/access.log', $logLine, FILE_APPEND | LOCK_EX);
|
||||
novacpx_log('warn', "Failed login for '$username' from $ip");
|
||||
Response::error('Invalid credentials', 401);
|
||||
}
|
||||
$user = $auth->user();
|
||||
audit('login', 'auth');
|
||||
Response::success([
|
||||
|
||||
Reference in New Issue
Block a user