diff --git a/data/web/debug.php b/data/web/debug.php index 0723ba6a..f9685ab4 100644 --- a/data/web/debug.php +++ b/data/web/debug.php @@ -23,7 +23,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
  • Postfix
  • Dovecot
  • SOGo
  • -
  • Fail2ban
  • +
  • Netfilter
  • Rspamd
  • Autodiscover
  • Watchdog
  • @@ -112,7 +112,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI']; 'redis-mailcow', 'php-fpm-mailcow', 'mysql-mailcow', - 'fail2ban-mailcow', + 'netfilter-mailcow', 'clamd-mailcow' ); foreach ($container_array as $container) { @@ -123,21 +123,26 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI']; setTimestamp(mktime( - $StartedAt['hour'], - $StartedAt['minute'], - $StartedAt['second'], - $StartedAt['month'], - $StartedAt['day'], - $StartedAt['year'])); - $user_tz = new DateTimeZone(getenv('TZ')); - $date->setTimezone($user_tz); - $started = $date->format('r'); + if ($StartedAt['hour'] !== false) { + $date = new \DateTime(); + $date->setTimestamp(mktime( + $StartedAt['hour'], + $StartedAt['minute'], + $StartedAt['second'], + $StartedAt['month'], + $StartedAt['day'], + $StartedAt['year'])); + $user_tz = new DateTimeZone(getenv('TZ')); + $date->setTimezone($user_tz); + $started = $date->format('r'); + } + else { + $started = '?'; + } ?> (Started on ), Restart -     +     -
    +
    -
    Fail2ban +
    Netfilter
    - - - + + +
    -
    +
    diff --git a/data/web/edit.php b/data/web/edit.php index 43e055ca..1611a6af 100644 --- a/data/web/edit.php +++ b/data/web/edit.php @@ -661,7 +661,7 @@ if (isset($_SESSION['mailcow_cc_role'])) { ?>

    Recipient map:


    -
    +
    @@ -679,7 +679,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
    - +
    diff --git a/data/web/favicon.png b/data/web/favicon.png index 6390041d..69eb2fcd 100644 Binary files a/data/web/favicon.png and b/data/web/favicon.png differ diff --git a/data/web/img/cow_lock.svg b/data/web/img/cow_lock.svg new file mode 100644 index 00000000..2be88dec --- /dev/null +++ b/data/web/img/cow_lock.svg @@ -0,0 +1,198 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/data/web/inc/functions.docker.inc.php b/data/web/inc/functions.docker.inc.php index 5b6afa9f..11747f25 100644 --- a/data/web/inc/functions.docker.inc.php +++ b/data/web/inc/functions.docker.inc.php @@ -7,6 +7,7 @@ function docker($service_name, $action, $attr1 = null, $attr2 = null, $extra_hea curl_setopt($curl, CURLOPT_URL, 'http://dockerapi:8080/containers/json'); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_POST, 0); + curl_setopt($curl, CURLOPT_TIMEOUT, 4); $response = curl_exec($curl); if ($response === false) { $err = curl_error($curl); @@ -32,6 +33,7 @@ function docker($service_name, $action, $attr1 = null, $attr2 = null, $extra_hea curl_setopt($curl, CURLOPT_URL, 'http://dockerapi:8080/containers/' . $container_id . '/json'); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_POST, 0); + curl_setopt($curl, CURLOPT_TIMEOUT, 4); $response = curl_exec($curl); if ($response === false) { $err = curl_error($curl); @@ -58,6 +60,7 @@ function docker($service_name, $action, $attr1 = null, $attr2 = null, $extra_hea if (ctype_xdigit($container_id) && ctype_alnum($attr1)) { curl_setopt($curl, CURLOPT_URL, 'http://dockerapi:8080/containers/' . $container_id . '/' . $attr1); curl_setopt($curl, CURLOPT_POST, 1); + curl_setopt($curl, CURLOPT_TIMEOUT, 4); if (!empty($attr2)) { curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($attr2)); } diff --git a/data/web/inc/functions.fail2ban.inc.php b/data/web/inc/functions.fail2ban.inc.php index b78fb36a..5acbf60f 100644 --- a/data/web/inc/functions.fail2ban.inc.php +++ b/data/web/inc/functions.fail2ban.inc.php @@ -4,30 +4,26 @@ function fail2ban($_action, $_data = null) { global $lang; switch ($_action) { case 'get': - $data = array(); + $f2b_options = array(); if ($_SESSION['mailcow_cc_role'] != "admin") { return false; } try { - $data['ban_time'] = $redis->Get('F2B_BAN_TIME'); - $data['max_attempts'] = $redis->Get('F2B_MAX_ATTEMPTS'); - $data['retry_window'] = $redis->Get('F2B_RETRY_WINDOW'); - $data['netban_ipv4'] = $redis->Get('F2B_NETBAN_IPV4'); - $data['netban_ipv6'] = $redis->Get('F2B_NETBAN_IPV6'); + $f2b_options = json_decode($redis->Get('F2B_OPTIONS'), true); $wl = $redis->hGetAll('F2B_WHITELIST'); if (is_array($wl)) { foreach ($wl as $key => $value) { $tmp_data[] = $key; } if (isset($tmp_data)) { - $data['whitelist'] = implode(PHP_EOL, $tmp_data); + $f2b_options['whitelist'] = implode(PHP_EOL, $tmp_data); } else { - $data['whitelist'] = ""; + $f2b_options['whitelist'] = ""; } } else { - $data['whitelist'] = ""; + $f2b_options['whitelist'] = ""; } } catch (RedisException $e) { @@ -37,7 +33,7 @@ function fail2ban($_action, $_data = null) { ); return false; } - return $data; + return $f2b_options; break; case 'edit': if ($_SESSION['mailcow_cc_role'] != "admin") { @@ -63,21 +59,16 @@ function fail2ban($_action, $_data = null) { return false; } $wl = $_data['whitelist']; - $ban_time = ($ban_time < 60) ? 60 : $ban_time; - - $netban_ipv4 = ($netban_ipv4 < 8) ? 8 : $netban_ipv4; - $netban_ipv6 = ($netban_ipv6 < 8) ? 8 : $netban_ipv6; - $netban_ipv4 = ($netban_ipv4 > 32) ? 32 : $netban_ipv4; - $netban_ipv6 = ($netban_ipv6 > 128) ? 128 : $netban_ipv6; - - $max_attempts = ($max_attempts < 1) ? 1 : $max_attempts; - $retry_window = ($retry_window < 1) ? 1 : $retry_window; + $f2b_options = array(); + $f2b_options['ban_time'] = ($ban_time < 60) ? 60 : $ban_time; + $f2b_options['netban_ipv4'] = ($netban_ipv4 < 8) ? 8 : $netban_ipv4; + $f2b_options['netban_ipv6'] = ($netban_ipv6 < 8) ? 8 : $netban_ipv6; + $f2b_options['netban_ipv4'] = ($netban_ipv4 > 32) ? 32 : $netban_ipv4; + $f2b_options['netban_ipv6'] = ($netban_ipv6 > 128) ? 128 : $netban_ipv6; + $f2b_options['max_attempts'] = ($max_attempts < 1) ? 1 : $max_attempts; + $f2b_options['retry_window'] = ($retry_window < 1) ? 1 : $retry_window; try { - $redis->Set('F2B_BAN_TIME', $ban_time); - $redis->Set('F2B_MAX_ATTEMPTS', $max_attempts); - $redis->Set('F2B_RETRY_WINDOW', $retry_window); - $redis->Set('F2B_NETBAN_IPV4', $netban_ipv4); - $redis->Set('F2B_NETBAN_IPV6', $netban_ipv6); + $redis->Set('F2B_OPTIONS', json_encode($f2b_options)); $redis->Del('F2B_WHITELIST'); if(!empty($wl)) { $wl_array = array_map('trim', preg_split( "/( |,|;|\n)/", $wl)); diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index f7f08403..54ca415e 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -1134,13 +1134,13 @@ function get_logs($container, $lines = false) { return $data_array; } } - if ($container == "fail2ban-mailcow") { + if ($container == "netfilter-mailcow") { if (!is_numeric($lines)) { list ($from, $to) = explode('-', $lines); - $data = $redis->lRange('F2B_LOG', intval($from), intval($to)); + $data = $redis->lRange('NETFILTER_LOG', intval($from), intval($to)); } else { - $data = $redis->lRange('F2B_LOG', 0, intval($lines)); + $data = $redis->lRange('NETFILTER_LOG', 0, intval($lines)); } if ($data) { foreach ($data as $json_line) { diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index f3577d50..f059ced0 100644 --- a/data/web/inc/init_db.inc.php +++ b/data/web/inc/init_db.inc.php @@ -3,7 +3,7 @@ function init_db_schema() { try { global $pdo; - $db_version = "27012018_1721"; + $db_version = "30012018_1521"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -21,10 +21,6 @@ function init_db_schema() { AND active = '1' AND address NOT LIKE '@%' GROUP BY goto;", - "grouped_sender_acl" => "CREATE VIEW grouped_sender_acl (username, send_as_acl) AS - SELECT logged_in_as, IFNULL(GROUP_CONCAT(send_as SEPARATOR ' '), '') AS send_as_acl FROM sender_acl - WHERE send_as NOT LIKE '@%' - GROUP BY logged_in_as;", "grouped_domain_alias_address" => "CREATE VIEW grouped_domain_alias_address (username, ad_alias) AS SELECT username, IFNULL(GROUP_CONCAT(local_part, '@', alias_domain SEPARATOR ' '), '') AS ad_alias FROM mailbox LEFT OUTER JOIN alias_domain ON target_domain=domain @@ -193,7 +189,6 @@ function init_db_schema() { "tls_enforce_out" => "TINYINT(1) NOT NULL DEFAULT '0'", "kind" => "VARCHAR(100) NOT NULL DEFAULT ''", "multiple_bookings" => "TINYINT(1) NOT NULL DEFAULT '0'", - "wants_tagged_subject" => "TINYINT(1) NOT NULL DEFAULT '0'", "created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)", "modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP", "active" => "TINYINT(1) NOT NULL DEFAULT '1'" @@ -250,7 +245,8 @@ function init_db_schema() { "eas_reset" => "TINYINT(1) NOT NULL DEFAULT '1'", "filters" => "TINYINT(1) NOT NULL DEFAULT '1'", "quarantaine" => "TINYINT(1) NOT NULL DEFAULT '1'", - "bcc_maps" => "TINYINT(1) NOT NULL DEFAULT '1'", + "bcc_maps" => "TINYINT(1) NOT NULL DEFAULT '0'", + "recipient_maps" => "TINYINT(1) NOT NULL DEFAULT '0'", ), "keys" => array( "fkey" => array( diff --git a/data/web/js/debug.js b/data/web/js/debug.js index 48ebd5e9..4ffcc044 100644 --- a/data/web/js/debug.js +++ b/data/web/js/debug.js @@ -31,9 +31,9 @@ jQuery(function($){ e.preventDefault(); draw_acme_logs(); }); - $("#refresh_fail2ban_log").on('click', function(e) { + $("#refresh_netfilter_log").on('click', function(e) { e.preventDefault(); - draw_fail2ban_logs(); + draw_netfilter_logs(); }); $("#refresh_rspamd_history").on('click', function(e) { e.preventDefault(); @@ -206,8 +206,8 @@ jQuery(function($){ } }); } - function draw_fail2ban_logs() { - ft_fail2ban_logs = FooTable.init('#fail2ban_log', { + function draw_netfilter_logs() { + ft_netfilter_logs = FooTable.init('#netfilter_log', { "columns": [ {"name":"time","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleString();},"title":lang.time,"style":{"width":"170px"}}, {"name":"priority","title":lang.priority,"style":{"width":"80px"}}, @@ -215,10 +215,10 @@ jQuery(function($){ ], "rows": $.ajax({ dataType: 'json', - url: '/api/v1/get/logs/fail2ban', + url: '/api/v1/get/logs/netfilter', jsonp: false, error: function () { - console.log('Cannot draw fail2ban log table'); + console.log('Cannot draw netfilter log table'); }, success: function (data) { return process_table_data(data, 'general_syslog'); @@ -497,7 +497,7 @@ jQuery(function($){ draw_watchdog_logs(); draw_acme_logs(); draw_api_logs(); - draw_fail2ban_logs(); + draw_netfilter_logs(); draw_rspamd_history(); -}); \ No newline at end of file +}); diff --git a/data/web/json_api.php b/data/web/json_api.php index 8c2c5b44..9d6e9761 100644 --- a/data/web/json_api.php +++ b/data/web/json_api.php @@ -880,14 +880,14 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u echo '{}'; } break; - case "fail2ban": + case "netfilter": // 0 is first record, so empty is fine if (isset($extra)) { $extra = preg_replace('/[^\d\-]/i', '', $extra); - $logs = get_logs('fail2ban-mailcow', $extra); + $logs = get_logs('netfilter-mailcow', $extra); } else { - $logs = get_logs('fail2ban-mailcow'); + $logs = get_logs('netfilter-mailcow'); } if (isset($logs) && !empty($logs)) { echo json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); diff --git a/data/web/lang/lang.de.php b/data/web/lang/lang.de.php index a874eea1..71587fcf 100644 --- a/data/web/lang/lang.de.php +++ b/data/web/lang/lang.de.php @@ -666,3 +666,14 @@ $lang['mailbox']['bcc_to_rcpt'] = "Map empfängerabhängig verwenden"; $lang['mailbox']['add_bcc_entry'] = "BCC-Eintrag hinzufügen"; $lang['mailbox']['bcc_info'] = "Eine empfängerabhängige Map wird verwendet, wenn die BCC-Map Eintragung auf den Eingang einer E-Mail auf das lokale Ziel reagieren soll. Senderabhängige Maps verfahren nach dem gleichen Prinzip.
    Das lokale Ziel wird bei Fehlzustellungen an ein BCC-Ziel nicht informiert."; +$lang['mailbox']['address_rewriting'] = 'Adressumschreibung'; +$lang['mailbox']['recipient_maps'] = 'Empfängerumschreibungen'; +$lang['mailbox']['recipient_map_info'] = 'Empfängerumschreibung ersetzen den Empfänger einer E-Mail vor dem Versand.'; +$lang['mailbox']['recipient_map_old'] = 'Original Empfänger'; +$lang['mailbox']['recipient_map_new'] = 'Neuer Empfänger'; +$lang['mailbox']['add_recipient_map_entry'] = 'Empfängerumschreibung hinzufügen'; +$lang['mailbox']['sender_maps'] = 'Senderumschreibungen'; +$lang['mailbox']['sender_map_info'] = 'Senderumschreibungen werden verwendet, um den Absender einer E-Mail noch vor dem Versand umzuschreiben.'; +$lang['mailbox']['sender_map_old'] = 'Original Absender'; +$lang['mailbox']['sender_map_new'] = 'Neuer Absender'; +$lang['mailbox']['add_sender_map_entry'] = 'Senderumschreibung hinzufügen'; \ No newline at end of file diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php index 41795bc3..50eb64f9 100644 --- a/data/web/lang/lang.en.php +++ b/data/web/lang/lang.en.php @@ -666,4 +666,9 @@ $lang['mailbox']['recipient_maps'] = 'Recipient maps'; $lang['mailbox']['recipient_map_info'] = 'Recipient maps are used to replace the destination address on a message before it is delivered.'; $lang['mailbox']['recipient_map_old'] = 'Original recipient'; $lang['mailbox']['recipient_map_new'] = 'New recipient'; -$lang['mailbox']['add_recipient_map_entry'] = 'Add recipient map'; \ No newline at end of file +$lang['mailbox']['add_recipient_map_entry'] = 'Add recipient map'; +$lang['mailbox']['sender_maps'] = 'Sender maps'; +$lang['mailbox']['sender_map_info'] = 'Sender maps are used to replace the sender address on a message before it is sent.'; +$lang['mailbox']['sender_map_old'] = 'Original sender'; +$lang['mailbox']['sender_map_new'] = 'New sender'; +$lang['mailbox']['add_sender_map_entry'] = 'Add sender map'; \ No newline at end of file