mirror of
https://github.com/swissmakers/fail2ban-ui.git
synced 2026-04-17 05:53:15 +02:00
Restructure an adding basic sections 2/2
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
<!--
|
||||
Fail2ban UI - A Swiss made, management interface for Fail2ban.
|
||||
|
||||
Copyright (C) 2025 Swissmakers GmbH
|
||||
Copyright (C) 2026 Swissmakers GmbH
|
||||
|
||||
Licensed under the GNU General Public License, Version 3 (GPL-3.0)
|
||||
You may not use this file except in compliance with the License.
|
||||
@@ -22,21 +22,14 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
|
||||
<title data-i18n="page.title">Fail2ban UI Dashboard</title>
|
||||
<!-- Prism.js for syntax highlighting -->
|
||||
<link rel="stylesheet" href="/static/vendor/prism/prism-tomorrow.min.css?v={{.version}}" />
|
||||
<script src="/static/vendor/prism/prism-core.min.js?v={{.version}}"></script>
|
||||
<script src="/static/vendor/prism/prism-autoloader.min.js?v={{.version}}"></script>
|
||||
<!-- Tailwind CSS -->
|
||||
<link rel="stylesheet" href="/static/tailwind.css?v={{.version}}">
|
||||
<!-- Font Awesome for icons -->
|
||||
<link rel="stylesheet" href="/static/vendor/fontawesome/all.min.css?v={{.version}}">
|
||||
<!-- Select2 CSS -->
|
||||
<link rel="stylesheet" href="/static/vendor/select2/select2.min.css?v={{.version}}" />
|
||||
<!-- Fail2ban UI CSS -->
|
||||
<link rel="stylesheet" href="/static/fail2ban-ui.css?v={{.version}}">
|
||||
<!-- LOTR Theme CSS (loaded conditionally) -->
|
||||
<link rel="stylesheet" href="/static/lotr.css?v={{.version}}" id="lotr-css" disabled>
|
||||
<!-- Google Fonts for LOTR theme -->
|
||||
<link rel="stylesheet" href="/static/vendor/fonts/google-fonts.css?v={{.version}}">
|
||||
</head>
|
||||
|
||||
@@ -80,7 +73,6 @@
|
||||
<div id="clockDisplay" class="ml-4 text-sm font-mono">
|
||||
<span id="clockTime">--:--:--</span>
|
||||
</div>
|
||||
<!-- User info and logout (shown when authenticated) -->
|
||||
<div id="userInfoContainer" class="hidden ml-4 flex items-center gap-3 border-l border-blue-500 pl-4">
|
||||
<div class="relative">
|
||||
<button id="userMenuButton" onclick="toggleUserMenu()" class="flex items-center gap-2 px-3 py-2 rounded text-sm font-medium hover:bg-blue-700 transition-colors focus:outline-none">
|
||||
@@ -89,7 +81,6 @@
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- User dropdown menu -->
|
||||
<div id="userMenuDropdown" class="hidden absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 z-50 border border-gray-200">
|
||||
<div class="px-4 py-2 border-b border-gray-200">
|
||||
<div class="text-sm font-medium text-gray-900" id="userMenuDisplayName"></div>
|
||||
@@ -116,7 +107,6 @@
|
||||
<a href="#" onclick="showSection('dashboardSection')" class="block px-3 py-2 rounded-md text-base font-medium hover:bg-blue-700 transition-colors" data-i18n="nav.dashboard">Dashboard</a>
|
||||
<a href="#" onclick="showSection('filterSection')" class="block px-3 py-2 rounded-md text-base font-medium hover:bg-blue-700 transition-colors" data-i18n="nav.filter_debug">Filter Debug</a>
|
||||
<a href="#" onclick="showSection('settingsSection')" class="block px-3 py-2 rounded-md text-base font-medium hover:bg-blue-700 transition-colors" data-i18n="nav.settings">Settings</a>
|
||||
<!-- User info and logout in mobile menu (shown when authenticated) -->
|
||||
<div id="mobileUserInfoContainer" class="hidden border-t border-blue-500 mt-2 pt-2">
|
||||
<div class="px-3 py-2">
|
||||
<div class="text-sm font-medium" id="mobileUserDisplayName"></div>
|
||||
@@ -126,15 +116,17 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Mobile menu END -->
|
||||
</nav>
|
||||
<!-- ************************ Navigation END *************************** -->
|
||||
|
||||
<!-- Login Page (hidden by default, shown only when OIDC enabled and not authenticated) -->
|
||||
|
||||
<!-- ******************************************************************* -->
|
||||
<!-- Login Page START -->
|
||||
<!-- ******************************************************************* -->
|
||||
<div id="loginPage" class="hidden min-h-screen flex items-center justify-center bg-gray-100 py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div class="max-w-md w-full">
|
||||
<!-- Login Card -->
|
||||
<div class="bg-white rounded-lg shadow-lg p-8 border border-gray-200">
|
||||
<!-- Logo and Title -->
|
||||
<div class="text-center mb-8">
|
||||
<div class="mx-auto flex items-center justify-center h-16 w-16 rounded-full bg-blue-600 mb-4">
|
||||
<svg class="h-10 w-10 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
@@ -144,8 +136,6 @@
|
||||
<h2 class="text-3xl font-bold text-gray-900 mb-2" data-i18n="auth.login_title">Sign in to Fail2ban UI</h2>
|
||||
<p class="text-sm text-gray-600" data-i18n="auth.login_description">Please authenticate to access the management interface</p>
|
||||
</div>
|
||||
|
||||
<!-- Error Message -->
|
||||
<div id="loginError" class="hidden bg-red-50 border-l-4 border-red-400 text-red-700 px-4 py-3 rounded mb-6">
|
||||
<div class="flex">
|
||||
<div class="flex-shrink-0">
|
||||
@@ -158,8 +148,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Login Button -->
|
||||
<div class="mb-6">
|
||||
<button type="button" onclick="handleLogin()" class="w-full flex justify-center items-center py-3 px-4 border border-transparent text-base font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors">
|
||||
<svg class="h-5 w-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
@@ -167,8 +155,6 @@
|
||||
</svg>
|
||||
<span data-i18n="auth.login_button">Sign in with OIDC</span>
|
||||
</button>
|
||||
|
||||
<!-- Loading State -->
|
||||
<div id="loginLoading" class="hidden text-center py-4">
|
||||
<div class="inline-flex items-center">
|
||||
<div class="h-5 w-5 border-2 border-blue-500 border-t-transparent rounded-full animate-spin mr-3"></div>
|
||||
@@ -176,8 +162,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer Info -->
|
||||
<div class="pt-6 border-t border-gray-200">
|
||||
<p class="text-xs text-center text-gray-500">
|
||||
Secure authentication via OpenID Connect
|
||||
@@ -186,12 +170,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ********************** Login Page END ******************************* -->
|
||||
|
||||
|
||||
<!-- Main Content -->
|
||||
<main id="mainContent" class="hidden max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
||||
<!-- ******************************************************************* -->
|
||||
<!-- Dashboard Page START -->
|
||||
<!-- ******************************************************************* -->
|
||||
|
||||
<!-- ******************************************************************* -->
|
||||
<!-- Dashboard Section START -->
|
||||
<!-- ******************************************************************* -->
|
||||
<div id="dashboardSection">
|
||||
<div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between mb-6">
|
||||
<div>
|
||||
@@ -220,15 +206,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="dashboard"></div> <!-- Dynamic content from the API -->
|
||||
<div id="dashboard"></div>
|
||||
</div>
|
||||
<!-- ********************** Dashboard Page END ************************* -->
|
||||
<!-- ********************** Dashboard Section END ********************** -->
|
||||
|
||||
|
||||
<!-- ******************************************************************* -->
|
||||
<!-- Filter-Debug Page START -->
|
||||
<!-- ******************************************************************* -->
|
||||
<!-- ******************************************************************* -->
|
||||
<!-- Filter-Debug Section START -->
|
||||
<!-- ******************************************************************* -->
|
||||
<div id="filterSection" class="hidden">
|
||||
<h2 class="text-2xl font-bold text-gray-800 mb-6" data-i18n="filter_debug.title">Filter Debug</h2>
|
||||
|
||||
@@ -246,8 +231,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Textarea for filter content (readonly by default, editable with Edit button) -->
|
||||
<div class="mb-4">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<label for="filterContentTextarea" class="block text-sm font-medium text-gray-700" data-i18n="filter_debug.filter_content">Filter Content</label>
|
||||
@@ -258,8 +241,6 @@
|
||||
<textarea id="filterContentTextarea" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 h-40 font-mono text-sm bg-gray-50"
|
||||
placeholder="Filter content will appear here when a filter is selected..." readonly></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Textarea for log lines to test -->
|
||||
<div class="mb-4">
|
||||
<label for="logLinesTextarea" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="filter_debug.log_lines">Log Lines</label>
|
||||
<textarea id="logLinesTextarea" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 h-40"
|
||||
@@ -271,21 +252,19 @@
|
||||
|
||||
<div id="testResults" class="hidden bg-gray-900 rounded-lg shadow p-6 text-white font-mono text-sm"></div>
|
||||
</div>
|
||||
<!-- ********************* Filter-Debug Page END *********************** -->
|
||||
<!-- ********************* Filter-Debug Page END *********************** -->
|
||||
|
||||
|
||||
<!-- ******************************************************************* -->
|
||||
<!-- Settings Page START -->
|
||||
<!-- ******************************************************************* -->
|
||||
<!-- ******************************************************************* -->
|
||||
<!-- Settings Page START -->
|
||||
<!-- ******************************************************************* -->
|
||||
<div id="settingsSection" class="hidden">
|
||||
<h2 class="text-2xl font-bold text-gray-800 mb-6" data-i18n="settings.title">Settings</h2>
|
||||
|
||||
<form onsubmit="saveSettings(event)" class="space-y-6">
|
||||
<!-- General Settings Group -->
|
||||
<!-- ========================= General Settings ========================= -->
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<h3 class="text-lg font-medium text-gray-900 mb-4" data-i18n="settings.general">General Settings</h3>
|
||||
|
||||
<!-- Language Selection -->
|
||||
<div class="mb-4">
|
||||
<label for="languageSelect" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.language">Language</label>
|
||||
<select id="languageSelect" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
@@ -297,8 +276,6 @@
|
||||
<option value="de_ch">Schwiizerdütsch</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Fail2Ban UI Port (server) -->
|
||||
<div class="mb-4">
|
||||
<label for="uiPort" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.server_port">Server Port</label>
|
||||
<input type="number" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" id="uiPort"
|
||||
@@ -319,7 +296,6 @@
|
||||
</p>
|
||||
<p class="text-xs text-gray-500 mt-1" id="callbackUrlDefaultHint" data-i18n="settings.callback_url_hint">This URL is used by all Fail2Ban instances to send ban alerts back to Fail2Ban UI. For local deployments, use the same port as Fail2Ban UI (e.g., http://127.0.0.1:8080). For reverse proxy setups, use your TLS-encrypted endpoint (e.g., https://fail2ban.example.com).</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<label for="callbackSecret" class="block text-sm font-medium text-gray-700" data-i18n="settings.callback_secret">Fail2ban Callback URL Secret</label>
|
||||
@@ -329,8 +305,6 @@
|
||||
data-i18n-placeholder="settings.callback_secret_placeholder" placeholder="Auto-generated 42-character secret" />
|
||||
<p class="text-xs text-gray-500 mt-1" data-i18n="settings.callback_secret.description">This secret is automatically generated and used to authenticate ban notification requests. It is included in the fail2ban action configuration.</p>
|
||||
</div>
|
||||
|
||||
<!-- Debug Log Output -->
|
||||
<div class="flex items-center gap-4 border border-gray-200 rounded-lg p-2 overflow-x-auto bg-gray-50">
|
||||
<div class="flex items-center">
|
||||
<input type="checkbox" id="debugMode" class="h-4 w-7 text-blue-600 transition duration-150 ease-in-out">
|
||||
@@ -341,8 +315,6 @@
|
||||
<label for="consoleOutput" class="ml-2 block text-sm text-gray-700" data-i18n="settings.enable_console">Enable Console Output</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Console Output Window -->
|
||||
<div id="consoleOutputContainer" class="hidden mt-4 border border-gray-700 rounded-lg bg-gray-900 shadow-lg overflow-hidden">
|
||||
<div class="flex items-center justify-between bg-gray-800 px-4 py-2 border-b border-gray-700">
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -361,7 +333,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Advanced Actions -->
|
||||
<!-- ========================= Advanced Actions ========================= -->
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<div class="flex flex-col gap-2 md:flex-row md:items-start md:justify-between">
|
||||
<div>
|
||||
@@ -373,19 +345,16 @@
|
||||
<button type="button" class="px-3 py-2 text-sm rounded border border-blue-600 text-blue-600 hover:bg-blue-50" onclick="openAdvancedTestModal()" data-i18n="settings.advanced.test_button">Manually Block / Test</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 space-y-4">
|
||||
<div class="flex items-center">
|
||||
<input type="checkbox" id="advancedActionsEnabled" class="h-4 w-4 text-blue-600 border-gray-300 rounded">
|
||||
<label for="advancedActionsEnabled" class="ml-2 text-sm text-gray-700" data-i18n="settings.advanced.enable">Enable automatic permanent blocking</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="advancedThreshold" class="block text-sm font-medium text-gray-700" data-i18n="settings.advanced.threshold">Threshold before permanent block</label>
|
||||
<input type="number" id="advancedThreshold" min="1" class="mt-1 w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="5">
|
||||
<p class="text-xs text-gray-500 mt-1" data-i18n="settings.advanced.threshold_hint">If an IP is banned at least this many times it will be forwarded to the selected firewall integration.</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="advancedIntegrationSelect" class="block text-sm font-medium text-gray-700" data-i18n="settings.advanced.integration">Integration</label>
|
||||
<select id="advancedIntegrationSelect" class="mt-1 w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
@@ -426,7 +395,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="advancedPfSenseFields" class="hidden border border-gray-200 rounded-lg p-4 overflow-x-auto bg-gray-50">
|
||||
<p class="text-sm text-gray-500 mb-3" data-i18n="settings.advanced.pfsense.note">Requires the pfSense REST API package. Enter the API key and alias to manage.</p>
|
||||
<div class="mb-3 text-sm">
|
||||
@@ -454,7 +422,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="advancedOPNsenseFields" class="hidden border border-gray-200 rounded-lg p-4 overflow-x-auto bg-gray-50">
|
||||
<p class="text-sm text-gray-500 mb-3" data-i18n="settings.advanced.opnsense.note">Enter the OPNsense API credentials and alias to manage.</p>
|
||||
<div class="mb-3 text-sm">
|
||||
@@ -486,7 +453,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<h4 class="text-md font-semibold text-gray-800 mb-2" data-i18n="settings.advanced.log_title">Permanent Block Log</h4>
|
||||
<div id="permanentBlockLog" class="overflow-x-auto border border-gray-200 rounded-md">
|
||||
@@ -495,11 +461,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Alert Settings Group -->
|
||||
<!-- ========================= Alert Settings =========================== -->
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<h3 class="text-lg font-medium text-gray-900 mb-4" data-i18n="settings.alert">Alert Settings</h3>
|
||||
|
||||
<!-- Email Alert Preferences -->
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.email_alerts">Email Alert Preferences</label>
|
||||
<div class="space-y-2">
|
||||
@@ -513,15 +477,12 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4" id="emailFieldsContainer">
|
||||
<label for="destEmail" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.destination_email">Destination Email (Alerts Receiver)</label>
|
||||
<input type="email" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100 disabled:cursor-not-allowed" id="destEmail"
|
||||
data-i18n-placeholder="settings.destination_email_placeholder" placeholder="alerts@swissmakers.ch" />
|
||||
<p class="text-xs text-red-600 mt-1 hidden" id="destEmailError"></p>
|
||||
</div>
|
||||
|
||||
<!-- GeoIP Provider -->
|
||||
<div class="mb-4">
|
||||
<label for="geoipProvider" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.geoip_provider">GeoIP Provider</label>
|
||||
<select id="geoipProvider" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" onchange="onGeoIPProviderChange(this.value)">
|
||||
@@ -530,21 +491,16 @@
|
||||
</select>
|
||||
<p class="text-xs text-gray-500 mt-1" data-i18n="settings.geoip_provider.description">Choose the GeoIP lookup provider. MaxMind requires a local database file, while Built-in uses a free online API.</p>
|
||||
</div>
|
||||
|
||||
<!-- GeoIP Database Path (shown only for MaxMind) -->
|
||||
<div id="geoipDatabasePathContainer" class="mb-4">
|
||||
<label for="geoipDatabasePath" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.geoip_database_path">GeoIP Database Path</label>
|
||||
<input type="text" id="geoipDatabasePath" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="/usr/share/GeoIP/GeoLite2-Country.mmdb">
|
||||
<p class="text-xs text-gray-500 mt-1" data-i18n="settings.geoip_database_path.description">Path to the MaxMind GeoLite2-Country database file.</p>
|
||||
</div>
|
||||
|
||||
<!-- Max Log Lines -->
|
||||
<div class="mb-4">
|
||||
<label for="maxLogLines" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.max_log_lines">Maximum Log Lines</label>
|
||||
<input type="number" id="maxLogLines" min="1" max="500" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="50">
|
||||
<p class="text-xs text-gray-500 mt-1" data-i18n="settings.max_log_lines.description">Maximum number of log lines to include in ban notifications. Most relevant lines are selected automatically.</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="alertCountries" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.alert_countries">Alert Countries</label>
|
||||
<p class="text-sm text-gray-500 mb-2" data-i18n="settings.alert_countries_description">
|
||||
@@ -751,7 +707,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SMTP Configuration Group -->
|
||||
<!-- ========================= SMTP Configuration ======================= -->
|
||||
<div class="bg-white rounded-lg shadow p-6" id="smtpFieldsContainer">
|
||||
<h3 class="text-lg font-medium text-gray-900 mb-4" data-i18n="settings.smtp">SMTP Configuration</h3>
|
||||
<div class="mb-4">
|
||||
@@ -805,12 +761,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Fail2Ban Configuration Group -->
|
||||
<!-- ========================= Fail2Ban Defaults ======================== -->
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<h3 class="text-lg font-medium text-gray-900 mb-4" data-i18n="settings.fail2ban">Global Default Fail2Ban Configurations</h3>
|
||||
<p class="text-sm text-gray-600 mb-4" data-i18n="settings.fail2ban.description">These settings will be applied to all enabled Fail2Ban servers and stored in their jail.local [DEFAULT] section.</p>
|
||||
|
||||
<!-- Bantime Increment -->
|
||||
<div class="mb-4">
|
||||
<div class="flex items-center mb-2">
|
||||
<input type="checkbox" id="bantimeIncrement" class="h-4 w-7 text-blue-600 transition duration-150 ease-in-out" />
|
||||
@@ -818,8 +772,6 @@
|
||||
</div>
|
||||
<p class="text-xs text-gray-500 ml-9" data-i18n="settings.enable_bantime_increment.description">If set to true, the bantime will be calculated using the formula: bantime = findtime * (number of failures / maxretry) * (1 + bantime.rndtime).</p>
|
||||
</div>
|
||||
|
||||
<!-- Default Enabled -->
|
||||
<div class="mb-4">
|
||||
<div class="flex items-center mb-2">
|
||||
<input type="checkbox" id="defaultJailEnable" class="h-4 w-7 text-blue-600 transition duration-150 ease-in-out" />
|
||||
@@ -827,8 +779,6 @@
|
||||
</div>
|
||||
<p class="text-xs text-gray-500 ml-9" data-i18n="settings.default_jail_enable.description">If enabled, all jails will be enabled by default. When disabled, jails must be explicitly enabled.</p>
|
||||
</div>
|
||||
|
||||
<!-- Bantime -->
|
||||
<div class="mb-4">
|
||||
<label for="banTime" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.default_bantime">Default Bantime</label>
|
||||
<p class="text-xs text-gray-500 mb-2" data-i18n="settings.default_bantime.description">The number of seconds that a host is banned. Time format: 1h = 1 hour, 1d = 1 day, 1w = 1 week, 1m = 1 month, 1y = 1 year.</p>
|
||||
@@ -836,16 +786,12 @@
|
||||
data-i18n-placeholder="settings.default_bantime_placeholder" placeholder="e.g., 48h" />
|
||||
<p class="text-xs text-red-600 mt-1 hidden" id="banTimeError"></p>
|
||||
</div>
|
||||
|
||||
<!-- Bantime Rndtime (optional, for bantime increment formula) -->
|
||||
<div class="mb-4">
|
||||
<label for="bantimeRndtime" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.bantime_rndtime">Bantime Rndtime</label>
|
||||
<p class="text-xs text-gray-500 mb-2" data-i18n="settings.bantime_rndtime.description">Optional. Max random seconds added in bantime increment formula (e.g. 2048). Leave empty to use Fail2ban default.</p>
|
||||
<input type="text" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" id="bantimeRndtime"
|
||||
data-i18n-placeholder="settings.bantime_rndtime_placeholder" placeholder="e.g., 2048" />
|
||||
</div>
|
||||
|
||||
<!-- Banaction -->
|
||||
<div class="mb-4">
|
||||
<label for="banaction" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.banaction">Banaction</label>
|
||||
<p class="text-xs text-gray-500 mb-2" data-i18n="settings.banaction.description">Default banning action (e.g. nftables-multiport, nftables-allports, firewallcmd-rich-rules, etc). It is used to define action_* variables.</p>
|
||||
@@ -881,8 +827,6 @@
|
||||
<option value="apf">apf</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Banaction Allports -->
|
||||
<div class="mb-4">
|
||||
<label for="banactionAllports" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.banaction_allports">Banaction Allports</label>
|
||||
<p class="text-xs text-gray-500 mb-2" data-i18n="settings.banaction_allports.description">Banning action for all ports (e.g. iptables-allports, firewallcmd-allports, etc). Used when a jail needs to ban all ports instead of specific ones.</p>
|
||||
@@ -918,8 +862,6 @@
|
||||
<option value="apf">apf</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Default Chain -->
|
||||
<div class="mb-4">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<label for="defaultChain" class="block text-sm font-medium text-gray-700" data-i18n="settings.default_chain">Default Chain</label>
|
||||
@@ -932,8 +874,6 @@
|
||||
<option value="FORWARD" data-i18n="settings.chain_forward">FORWARD</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Findtime -->
|
||||
<div class="mb-4">
|
||||
<label for="findTime" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.default_findtime">Default Findtime</label>
|
||||
<p class="text-xs text-gray-500 mb-2" data-i18n="settings.default_findtime.description">A host is banned if it has generated 'maxretry' failures during the last 'findtime' seconds. Time format: 1h = 1 hour, 1d = 1 day, 1w = 1 week, 1m = 1 month, 1y = 1 year.</p>
|
||||
@@ -941,8 +881,6 @@
|
||||
data-i18n-placeholder="settings.default_findtime_placeholder" placeholder="e.g., 30m" />
|
||||
<p class="text-xs text-red-600 mt-1 hidden" id="findTimeError"></p>
|
||||
</div>
|
||||
|
||||
<!-- Max Retry -->
|
||||
<div class="mb-4">
|
||||
<label for="maxRetry" class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.default_max_retry">Default Max Retry</label>
|
||||
<p class="text-xs text-gray-500 mb-2" data-i18n="settings.default_max_retry.description">Number of failures before a host gets banned.</p>
|
||||
@@ -950,8 +888,6 @@
|
||||
data-i18n-placeholder="settings.default_max_retry_placeholder" placeholder="Enter maximum retries" min="1" />
|
||||
<p class="text-xs text-red-600 mt-1 hidden" id="maxRetryError"></p>
|
||||
</div>
|
||||
|
||||
<!-- Ignore IPs -->
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2" data-i18n="settings.ignore_ips">Ignore IPs</label>
|
||||
<p class="text-xs text-gray-500 mb-2" data-i18n="settings.ignore_ips.description">Space separated list of IP addresses, CIDR masks or DNS hosts. Fail2ban will not ban a host which matches an address in this list.</p>
|
||||
@@ -962,16 +898,16 @@
|
||||
<div id="ignoreIPsError" class="hidden text-red-600 text-sm mt-1"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button type="submit" class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 transition-colors" data-i18n="settings.save">Save</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<!-- *********************** Settings Page END ************************* -->
|
||||
<!-- *********************** Settings Page END ************************* -->
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<!-- ******************************************************************* -->
|
||||
<!-- Footer -->
|
||||
<!-- ******************************************************************* -->
|
||||
<footer id="footer" class="hidden bg-gray-100 py-4">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center text-gray-600 text-sm">
|
||||
<p class="mb-0">
|
||||
@@ -988,11 +924,12 @@
|
||||
<!-- ******************************************************************* -->
|
||||
<!-- Modal Templates START -->
|
||||
<!-- ******************************************************************* -->
|
||||
<!-- Jail Config Modal -->
|
||||
|
||||
<!-- ========================= Jail Config Modal ========================= -->
|
||||
<div id="jailConfigModal" class="hidden fixed inset-0 z-50 overflow-y-auto" style="z-index: 60;">
|
||||
<div class="relative flex min-h-full w-full items-center justify-center p-2 sm:p-4">
|
||||
<div class="fixed inset-0 bg-gray-500 opacity-75" aria-hidden="true"></div>
|
||||
|
||||
|
||||
<div class="relative z-10 w-full rounded-lg bg-white text-left shadow-xl transition-all my-4 sm:my-8" style="max-width: 90vw; max-height: calc(100vh - 2rem); display: flex; flex-direction: column;">
|
||||
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4" style="flex: 1; overflow-y: auto; min-height: 0;">
|
||||
<div class="sm:flex sm:items-start">
|
||||
@@ -1008,7 +945,6 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-4 space-y-4">
|
||||
<!-- Filter Configuration -->
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<label class="block text-sm font-medium text-gray-700" data-i18n="modal.filter_config_label">Filter Configuration</label>
|
||||
@@ -1037,11 +973,7 @@
|
||||
onfocus="preventExtensionInterference(this);"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Divider -->
|
||||
<div class="border-t border-gray-300"></div>
|
||||
|
||||
<!-- Jail Configuration -->
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<label class="block text-sm font-medium text-gray-700" data-i18n="modal.jail_config_label">Jail Configuration</label>
|
||||
@@ -1070,8 +1002,6 @@
|
||||
onfocus="preventExtensionInterference(this);"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Test Logpath Button (only shown if logpath is set) -->
|
||||
<div id="testLogpathSection" class="hidden">
|
||||
<div id="localServerLogpathHint" class="mb-2 p-2 bg-blue-50 border border-blue-200 rounded-md text-xs text-blue-800 hidden">
|
||||
<strong data-i18n="modal.local_server_logpath_note">ℹ️ Note:</strong> <span data-i18n="modal.local_server_logpath_text_prefix">For a local fail2ban server (e.g. installed on container host system or in a container on same host), log files must also be mounted to the fail2ban-ui container (e.g.,</span> <code class="font-mono">-v /var/log:/var/log:ro</code> <span data-i18n="modal.local_server_logpath_text_suffix">) this is required so that the fail2ban-ui can verify logpath variables or paths when updating jails.</span>
|
||||
@@ -1094,7 +1024,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Manage Jails Modal -->
|
||||
<!-- ========================= Manage Jails Modal ======================== -->
|
||||
<div id="manageJailsModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
|
||||
<div class="relative flex min-h-full w-full items-center justify-center p-4 sm:p-6">
|
||||
<div class="fixed inset-0 bg-gray-500 opacity-75" aria-hidden="true"></div>
|
||||
@@ -1122,7 +1052,6 @@
|
||||
<span data-i18n="modal.create_jail">Create New Jail</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Dynamically filled list of jails with toggle switches -->
|
||||
<div id="jailsList" class="divide-y divide-gray-200"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1135,7 +1064,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Create Jail Modal -->
|
||||
<!-- ========================= Create Jail Modal ========================= -->
|
||||
<div id="createJailModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
|
||||
<div class="relative flex min-h-full w-full items-center justify-center p-4 sm:p-6">
|
||||
<div class="fixed inset-0 bg-gray-500 opacity-75" aria-hidden="true"></div>
|
||||
@@ -1182,7 +1111,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Create Filter Modal -->
|
||||
<!-- ========================= Create Filter Modal ======================= -->
|
||||
<div id="createFilterModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
|
||||
<div class="relative flex min-h-full w-full items-center justify-center p-4 sm:p-6">
|
||||
<div class="fixed inset-0 bg-gray-500 opacity-75" aria-hidden="true"></div>
|
||||
@@ -1222,7 +1151,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Server Manager Modal -->
|
||||
<!-- ========================= Server Manager Modal ====================== -->
|
||||
<div id="serverManagerModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
|
||||
<div class="relative flex min-h-full w-full items-center justify-center p-4 sm:p-6">
|
||||
<div class="fixed inset-0 bg-gray-500 opacity-75" aria-hidden="true"></div>
|
||||
@@ -1345,7 +1274,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Whois Modal -->
|
||||
<!-- ========================= Whois Modal =============================== -->
|
||||
<div id="whoisModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
|
||||
<div class="relative flex min-h-full w-full items-center justify-center p-4 sm:p-6">
|
||||
<div class="fixed inset-0 bg-gray-500 opacity-75" aria-hidden="true"></div>
|
||||
@@ -1377,7 +1306,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Advanced Actions Test Modal -->
|
||||
<!-- ========================= Advanced Actions Test Modal =============== -->
|
||||
<div id="advancedTestModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
|
||||
<div class="relative flex min-h-full w-full items-center justify-center p-4 sm:p-6">
|
||||
<div class="fixed inset-0 bg-gray-500 opacity-75" aria-hidden="true"></div>
|
||||
@@ -1411,7 +1340,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Logs Modal -->
|
||||
<!-- ========================= Logs Modal ================================ -->
|
||||
<div id="logsModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
|
||||
<div class="relative flex min-h-full w-full items-center justify-center p-4 sm:p-6">
|
||||
<div class="fixed inset-0 bg-gray-500 opacity-75" aria-hidden="true"></div>
|
||||
@@ -1446,7 +1375,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ban Insights Modal -->
|
||||
<!-- ========================= Ban Insights Modal ======================== -->
|
||||
<div id="banInsightsModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
|
||||
<div class="relative flex min-h-full w-full items-center justify-center p-4 sm:p-6">
|
||||
<div class="fixed inset-0 bg-gray-500 opacity-75" aria-hidden="true"></div>
|
||||
@@ -1464,13 +1393,8 @@
|
||||
</button>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 mb-4" data-i18n="logs.modal.insights_description">Country distribution and recurring offenders.</p>
|
||||
|
||||
<!-- Summary Cards -->
|
||||
<div id="insightsSummary" class="grid gap-4 sm:grid-cols-3 mb-6"></div>
|
||||
|
||||
<!-- Main Content Grid -->
|
||||
<div class="grid gap-6 lg:grid-cols-2">
|
||||
<!-- Country Statistics -->
|
||||
<div class="border border-gray-200 rounded-lg p-4 bg-gray-50">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div>
|
||||
@@ -1481,8 +1405,6 @@
|
||||
</div>
|
||||
<div id="countryStatsContainer" class="space-y-4 max-h-96 overflow-y-auto"></div>
|
||||
</div>
|
||||
|
||||
<!-- Recurring IPs -->
|
||||
<div class="border border-gray-200 rounded-lg p-4 bg-gray-50">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div>
|
||||
@@ -1504,7 +1426,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Chain Help Modal -->
|
||||
<!-- ========================= Chain Help Modal ========================== -->
|
||||
<div id="chainHelpModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
|
||||
<div class="relative flex min-h-full w-full items-center justify-center p-4 sm:p-6">
|
||||
<div class="fixed inset-0 bg-gray-500 opacity-75" aria-hidden="true"></div>
|
||||
@@ -1547,12 +1469,11 @@
|
||||
|
||||
<!-- ********************** Modal Templates END ************************ -->
|
||||
|
||||
<!-- jQuery (used by Select2) -->
|
||||
<!-- ******************************************************************* -->
|
||||
<!-- Script Includes -->
|
||||
<!-- ******************************************************************* -->
|
||||
<script src="/static/vendor/jquery/jquery-3.6.0.min.js?v={{.version}}"></script>
|
||||
<!-- Select2 JS -->
|
||||
<script src="/static/vendor/select2/select2.min.js?v={{.version}}"></script>
|
||||
|
||||
<!-- Fail2ban UI JavaScript Modules -->
|
||||
<script src="/static/js/globals.js?v={{.version}}"></script>
|
||||
<script src="/static/js/core.js?v={{.version}}"></script>
|
||||
<script src="/static/js/api.js?v={{.version}}"></script>
|
||||
|
||||
Reference in New Issue
Block a user