[Web] Allow to blacklist, whitelist and unban networks currently blocked plus minor other fixes to fail2ban logic
parent
26807823b4
commit
5e590ea119
|
@ -416,8 +416,36 @@ $tfa_data = get_tfa();
|
||||||
<label for="blacklist"><?=$lang['admin']['f2b_blacklist'];?>:</label>
|
<label for="blacklist"><?=$lang['admin']['f2b_blacklist'];?>:</label>
|
||||||
<textarea class="form-control" id="blacklist" name="blacklist" rows="5"><?=$f2b_data['blacklist'];?></textarea>
|
<textarea class="form-control" id="blacklist" name="blacklist" rows="5"><?=$f2b_data['blacklist'];?></textarea>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-default" id="add_item" data-id="f2b" data-api-url='edit/fail2ban' data-api-attr='{}' href="#"><span class="glyphicon glyphicon-check"></span> <?=$lang['admin']['save'];?></button>
|
<button class="btn btn-default" id="edit_selected" data-item="self" data-id="f2b" data-api-url='edit/fail2ban' data-api-attr='{}' href="#"><span class="glyphicon glyphicon-check"></span> <?=$lang['admin']['save'];?></button>
|
||||||
</form>
|
</form>
|
||||||
|
<hr>
|
||||||
|
<p class="help-block"><?=$lang['admin']['ban_list_info'];?></p>
|
||||||
|
<?php
|
||||||
|
if (empty($f2b_data['active_bans'])):
|
||||||
|
?>
|
||||||
|
<i><?=$lang['admin']['no_active_bans'];?></i>
|
||||||
|
<?php
|
||||||
|
endif;
|
||||||
|
foreach ($f2b_data['active_bans'] as $active_bans):
|
||||||
|
?>
|
||||||
|
<p><span class="label label-info" style="padding:4px;font-size:85%;"><span class="glyphicon glyphicon-filter"></span> <?=$active_bans['network'];?> (<?=$active_bans['banned_until'];?>) -
|
||||||
|
<?php
|
||||||
|
if ($active_bans['queued_for_unban'] == 0):
|
||||||
|
?>
|
||||||
|
<a id="edit_selected" data-item="<?=$active_bans['network'];?>" data-id="f2b-quick" data-api-url='edit/fail2ban' data-api-attr='{"action":"unban"}' href="#">[<?=$lang['admin']['queue_unban'];?>]</a>
|
||||||
|
<a id="edit_selected" data-item="<?=$active_bans['network'];?>" data-id="f2b-quick" data-api-url='edit/fail2ban' data-api-attr='{"action":"whitelist"}' href="#">[whitelist]</a>
|
||||||
|
<a id="edit_selected" data-item="<?=$active_bans['network'];?>" data-id="f2b-quick" data-api-url='edit/fail2ban' data-api-attr='{"action":"blacklist"}' href="#">[blacklist]</a>
|
||||||
|
<?php
|
||||||
|
else:
|
||||||
|
?>
|
||||||
|
<i><?=$lang['admin']['unban_pending'];?></i>
|
||||||
|
<?php
|
||||||
|
endif;
|
||||||
|
?>
|
||||||
|
</span></p>
|
||||||
|
<?php
|
||||||
|
endforeach;
|
||||||
|
?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,14 @@
|
||||||
<?php
|
<?php
|
||||||
|
function valid_network($network) {
|
||||||
|
$cidr = explode('/', $network);
|
||||||
|
if (filter_var($cidr[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && (!isset($cidr[1]) || ($cidr[1] >= 0 && $cidr[1] <= 32))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
elseif (filter_var($cidr[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && (!isset($cidr[1]) || ($cidr[1] >= 0 && $cidr[1] <= 128))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
function fail2ban($_action, $_data = null) {
|
function fail2ban($_action, $_data = null) {
|
||||||
global $redis;
|
global $redis;
|
||||||
global $lang;
|
global $lang;
|
||||||
|
@ -42,6 +52,22 @@ function fail2ban($_action, $_data = null) {
|
||||||
else {
|
else {
|
||||||
$f2b_options['blacklist'] = "";
|
$f2b_options['blacklist'] = "";
|
||||||
}
|
}
|
||||||
|
$active_bans = $redis->hGetAll('F2B_ACTIVE_BANS');
|
||||||
|
$queue_unban = $redis->hGetAll('F2B_QUEUE_UNBAN');
|
||||||
|
if (is_array($active_bans)) {
|
||||||
|
foreach ($active_bans as $network => $banned_until) {
|
||||||
|
$queued_for_unban = (isset($queue_unban[$network]) && $queue_unban[$network] == 1) ? 1 : 0;
|
||||||
|
$difference = $banned_until - time();
|
||||||
|
$f2b_options['active_bans'][] = array(
|
||||||
|
'queued_for_unban' => $queued_for_unban,
|
||||||
|
'network' => $network,
|
||||||
|
'banned_until' => sprintf('%02dh %02dm %02ds', ($difference/3600), ($difference/60%60), $difference%60)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$f2b_options['active_bans'] = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (RedisException $e) {
|
catch (RedisException $e) {
|
||||||
$_SESSION['return'] = array(
|
$_SESSION['return'] = array(
|
||||||
|
@ -60,6 +86,33 @@ function fail2ban($_action, $_data = null) {
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (isset($_data['action']) && !empty($_data['network'])) {
|
||||||
|
$networks = (array) $_data['network'];
|
||||||
|
foreach ($networks as $network) {
|
||||||
|
if ($_data['action'] == "unban") {
|
||||||
|
if (valid_network($network)) {
|
||||||
|
$redis->hSet('F2B_QUEUE_UNBAN', $network, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif ($_data['action'] == "whitelist") {
|
||||||
|
if (valid_network($network)) {
|
||||||
|
$redis->hSet('F2B_WHITELIST', $network, 1);
|
||||||
|
$redis->hDel('F2B_BLACKLIST', $network, 1);
|
||||||
|
$redis->hSet('F2B_QUEUE_UNBAN', $network, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif ($_data['action'] == "blacklist") {
|
||||||
|
if (valid_network($network)) {
|
||||||
|
$redis->hSet('F2B_BLACKLIST', $network, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$_SESSION['return'] = array(
|
||||||
|
'type' => 'success',
|
||||||
|
'msg' => sprintf($lang['success']['object_modified'], htmlspecialchars(implode(', ', $networks)))
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
$is_now = fail2ban('get');
|
$is_now = fail2ban('get');
|
||||||
if (!empty($is_now)) {
|
if (!empty($is_now)) {
|
||||||
$ban_time = intval((isset($_data['ban_time'])) ? $_data['ban_time'] : $is_now['ban_time']);
|
$ban_time = intval((isset($_data['ban_time'])) ? $_data['ban_time'] : $is_now['ban_time']);
|
||||||
|
@ -93,11 +146,7 @@ function fail2ban($_action, $_data = null) {
|
||||||
$wl_array = array_map('trim', preg_split( "/( |,|;|\n)/", $wl));
|
$wl_array = array_map('trim', preg_split( "/( |,|;|\n)/", $wl));
|
||||||
if (is_array($wl_array)) {
|
if (is_array($wl_array)) {
|
||||||
foreach ($wl_array as $wl_item) {
|
foreach ($wl_array as $wl_item) {
|
||||||
$cidr = explode('/', $wl_item);
|
if (valid_network($wl_item)) {
|
||||||
if (filter_var($cidr[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && (!isset($cidr[1]) || ($cidr[1] >= 0 && $cidr[1] <= 32))) {
|
|
||||||
$redis->hSet('F2B_WHITELIST', $wl_item, 1);
|
|
||||||
}
|
|
||||||
elseif (filter_var($cidr[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && (!isset($cidr[1]) || ($cidr[1] >= 0 && $cidr[1] <= 128))) {
|
|
||||||
$redis->hSet('F2B_WHITELIST', $wl_item, 1);
|
$redis->hSet('F2B_WHITELIST', $wl_item, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,11 +156,7 @@ function fail2ban($_action, $_data = null) {
|
||||||
$bl_array = array_map('trim', preg_split( "/( |,|;|\n)/", $bl));
|
$bl_array = array_map('trim', preg_split( "/( |,|;|\n)/", $bl));
|
||||||
if (is_array($bl_array)) {
|
if (is_array($bl_array)) {
|
||||||
foreach ($bl_array as $bl_item) {
|
foreach ($bl_array as $bl_item) {
|
||||||
$cidr = explode('/', $bl_item);
|
if (valid_network($bl_item)) {
|
||||||
if (filter_var($cidr[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && (!isset($cidr[1]) || ($cidr[1] >= 0 && $cidr[1] <= 32))) {
|
|
||||||
$redis->hSet('F2B_BLACKLIST', $bl_item, 1);
|
|
||||||
}
|
|
||||||
elseif (filter_var($cidr[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && (!isset($cidr[1]) || ($cidr[1] >= 0 && $cidr[1] <= 128))) {
|
|
||||||
$redis->hSet('F2B_BLACKLIST', $bl_item, 1);
|
$redis->hSet('F2B_BLACKLIST', $bl_item, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1119,7 +1119,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
|
||||||
process_edit_return(fwdhost('edit', array_merge(array('fwdhost' => $items), $attr)));
|
process_edit_return(fwdhost('edit', array_merge(array('fwdhost' => $items), $attr)));
|
||||||
break;
|
break;
|
||||||
case "fail2ban":
|
case "fail2ban":
|
||||||
process_edit_return(fail2ban('edit', $attr));
|
process_edit_return(fail2ban('edit', array_merge(array('network' => $items), $attr)));
|
||||||
break;
|
break;
|
||||||
case "ui_texts":
|
case "ui_texts":
|
||||||
process_edit_return(customize('edit', 'ui_texts', $attr));
|
process_edit_return(customize('edit', 'ui_texts', $attr));
|
||||||
|
|
|
@ -450,6 +450,10 @@ $lang['admin']['api_allow_from'] = "IP-Adressen für Zugriff";
|
||||||
$lang['admin']['api_key'] = "API-Key";
|
$lang['admin']['api_key'] = "API-Key";
|
||||||
$lang['admin']['activate_api'] = "API aktivieren";
|
$lang['admin']['activate_api'] = "API aktivieren";
|
||||||
$lang['admin']['regen_api_key'] = "API-Key regenerieren";
|
$lang['admin']['regen_api_key'] = "API-Key regenerieren";
|
||||||
|
$lang['admin']['ban_list_info'] = "Übersicht ausgesperrter Netzwerke: <b>Netzwerk (verbleibende Banzeit) - [Aktionen]</b>.<br />IPs, die zum Unban eingereiht werden, verlassen die Liste aktiver Bans nach wenigen Sekunden.";
|
||||||
|
$lang['admin']['unban_pending'] = "ausstehend";
|
||||||
|
$lang['admin']['queue_unban'] = "Unban einreihen";
|
||||||
|
$lang['admin']['no_active_bans'] = "Keine aktiven Bans";
|
||||||
|
|
||||||
$lang['admin']['quarantine'] = "Quarantäne";
|
$lang['admin']['quarantine'] = "Quarantäne";
|
||||||
$lang['admin']['quarantine_retention_size'] = "Rückhaltungen pro Mailbox<br />0 bedeutet <b>inaktiv</b>!";
|
$lang['admin']['quarantine_retention_size'] = "Rückhaltungen pro Mailbox<br />0 bedeutet <b>inaktiv</b>!";
|
||||||
|
|
|
@ -471,6 +471,10 @@ $lang['admin']['api_allow_from'] = "Allow API access from these IPs";
|
||||||
$lang['admin']['api_key'] = "API key";
|
$lang['admin']['api_key'] = "API key";
|
||||||
$lang['admin']['activate_api'] = "Activate API";
|
$lang['admin']['activate_api'] = "Activate API";
|
||||||
$lang['admin']['regen_api_key'] = "Regenerate API key";
|
$lang['admin']['regen_api_key'] = "Regenerate API key";
|
||||||
|
$lang['admin']['ban_list_info'] = "See a list of banned IPs below: <b>network (remaining ban time) - [actions]</b>.<br />IPs queued to be unbanned, will be removed from the active ban list within a few seconds.";
|
||||||
|
$lang['admin']['unban_pending'] = "unban pending";
|
||||||
|
$lang['admin']['queue_unban'] = "queue unban";
|
||||||
|
$lang['admin']['no_active_bans'] = "No active bans";
|
||||||
|
|
||||||
$lang['admin']['quarantine'] = "Quarantine";
|
$lang['admin']['quarantine'] = "Quarantine";
|
||||||
$lang['admin']['quarantine_retention_size'] = "Retentions per mailbox<br />0 indicates <b>inactive</b>!";
|
$lang['admin']['quarantine_retention_size'] = "Retentions per mailbox<br />0 indicates <b>inactive</b>!";
|
||||||
|
|
Loading…
Reference in New Issue