From 6dc0bdbfa377eef1198063bccd41bd86a0858800 Mon Sep 17 00:00:00 2001 From: Tomasz Orzechowski Date: Tue, 9 Jan 2024 22:03:24 +0100 Subject: [PATCH 001/138] Proper number of threads regex. --- helper-scripts/backup_and_restore.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helper-scripts/backup_and_restore.sh b/helper-scripts/backup_and_restore.sh index ee9f0202..9a056105 100755 --- a/helper-scripts/backup_and_restore.sh +++ b/helper-scripts/backup_and_restore.sh @@ -54,10 +54,10 @@ COMPOSE_FILE=${SCRIPT_DIR}/../docker-compose.yml ENV_FILE=${SCRIPT_DIR}/../.env THREADS=$(echo ${THREADS:-1}) -if ! [[ "${THREADS}" =~ ^[1-9]+$ ]] ; then +if ! [[ "${THREADS}" =~ ^[1-9][0-9]?$ ]] ; then echo "Thread input is not a number!" exit 1 -elif [[ "${THREADS}" =~ ^[1-9]+$ ]] ; then +elif [[ "${THREADS}" =~ ^[1-9][0-9]?$ ]] ; then echo "Using ${THREADS} Thread(s) for this run." echo "Notice: You can set the Thread count with the THREADS Variable before you run this script." fi From 1787c53d98ad2251bf2a945ac81358a61ee36664 Mon Sep 17 00:00:00 2001 From: Habetdin <15926758+Habetdin@users.noreply.github.com> Date: Tue, 30 Jan 2024 14:09:37 +0300 Subject: [PATCH 002/138] [Netfilter] respect ban time limits --- data/Dockerfiles/netfilter/main.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/data/Dockerfiles/netfilter/main.py b/data/Dockerfiles/netfilter/main.py index 62e0dda7..c3ca379c 100644 --- a/data/Dockerfiles/netfilter/main.py +++ b/data/Dockerfiles/netfilter/main.py @@ -114,8 +114,6 @@ def ban(address): global lock refreshF2boptions() - BAN_TIME = int(f2boptions['ban_time']) - BAN_TIME_INCREMENT = bool(f2boptions['ban_time_increment']) MAX_ATTEMPTS = int(f2boptions['max_attempts']) RETRY_WINDOW = int(f2boptions['retry_window']) NETBAN_IPV4 = '/' + str(f2boptions['netban_ipv4']) @@ -150,7 +148,7 @@ def ban(address): if bans[net]['attempts'] >= MAX_ATTEMPTS: cur_time = int(round(time.time())) - NET_BAN_TIME = BAN_TIME if not BAN_TIME_INCREMENT else BAN_TIME * 2 ** bans[net]['ban_counter'] + NET_BAN_TIME = calcNetBanTime(bans[net]['ban_counter']) logger.logCrit('Banning %s for %d minutes' % (net, NET_BAN_TIME / 60 )) if type(ip) is ipaddress.IPv4Address and int(f2boptions['manage_external']) != 1: with lock: @@ -277,12 +275,11 @@ def snat6(snat_target): tables.snat6(snat_target, os.getenv('IPV6_NETWORK', 'fd4d:6169:6c63:6f77::/64')) def autopurge(): + global f2boptions + while not quit_now: time.sleep(10) refreshF2boptions() - BAN_TIME = int(f2boptions['ban_time']) - MAX_BAN_TIME = int(f2boptions['max_ban_time']) - BAN_TIME_INCREMENT = bool(f2boptions['ban_time_increment']) MAX_ATTEMPTS = int(f2boptions['max_attempts']) QUEUE_UNBAN = r.hgetall('F2B_QUEUE_UNBAN') if QUEUE_UNBAN: @@ -290,9 +287,9 @@ def autopurge(): unban(str(net)) for net in bans.copy(): if bans[net]['attempts'] >= MAX_ATTEMPTS: - NET_BAN_TIME = BAN_TIME if not BAN_TIME_INCREMENT else BAN_TIME * 2 ** bans[net]['ban_counter'] + NET_BAN_TIME = calcNetBanTime(bans[net]['ban_counter']) TIME_SINCE_LAST_ATTEMPT = time.time() - bans[net]['last_attempt'] - if TIME_SINCE_LAST_ATTEMPT > NET_BAN_TIME or TIME_SINCE_LAST_ATTEMPT > MAX_BAN_TIME: + if TIME_SINCE_LAST_ATTEMPT > NET_BAN_TIME: unban(net) def mailcowChainOrder(): @@ -306,6 +303,16 @@ def mailcowChainOrder(): if quit_now: return quit_now, exit_code = tables.checkIPv6ChainOrder() +def calcNetBanTime(ban_counter): + global f2boptions + + BAN_TIME = int(f2boptions['ban_time']) + MAX_BAN_TIME = int(f2boptions['max_ban_time']) + BAN_TIME_INCREMENT = bool(f2boptions['ban_time_increment']) + NET_BAN_TIME = BAN_TIME if not BAN_TIME_INCREMENT else BAN_TIME * 2 ** ban_counter + NET_BAN_TIME = max([BAN_TIME, min([NET_BAN_TIME, MAX_BAN_TIME])]) + return NET_BAN_TIME + def isIpNetwork(address): try: ipaddress.ip_network(address, False) From 3cb9c2ece548c8cb8ce7f41a503ec32ea9c46bfc Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Fri, 9 Feb 2024 08:05:19 +0100 Subject: [PATCH 003/138] ui: fix wrong docs links ui: fixed broken Links to docs --- data/web/lang/lang.cs-cz.json | 2 +- data/web/lang/lang.da-dk.json | 2 +- data/web/lang/lang.de-de.json | 2 +- data/web/lang/lang.en-gb.json | 2 +- data/web/lang/lang.fr-fr.json | 2 +- data/web/lang/lang.it-it.json | 2 +- data/web/lang/lang.nl-nl.json | 2 +- data/web/lang/lang.pt-br.json | 2 +- data/web/lang/lang.ro-ro.json | 2 +- data/web/lang/lang.ru-ru.json | 2 +- data/web/lang/lang.si-si.json | 2 +- data/web/lang/lang.sk-sk.json | 2 +- data/web/lang/lang.sv-se.json | 2 +- data/web/lang/lang.uk-ua.json | 2 +- data/web/lang/lang.zh-cn.json | 2 +- data/web/lang/lang.zh-tw.json | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/data/web/lang/lang.cs-cz.json b/data/web/lang/lang.cs-cz.json index 2d0b1014..593f1cdc 100644 --- a/data/web/lang/lang.cs-cz.json +++ b/data/web/lang/lang.cs-cz.json @@ -547,7 +547,7 @@ "dns_records": "DNS záznamy", "dns_records_24hours": "Upozornění: Změnám v systému DNS může trvat až 24 hodin, než se zde správně zobrazí jejich aktuální stav. Můžete zde snadno zjistit, jak nastavit DNS záznamy a zda jsou všechny záznamy správně uloženy.", "dns_records_data": "Správný záznam", - "dns_records_docs": "Přečtěte si prosím dokumentaci.", + "dns_records_docs": "Přečtěte si prosím dokumentaci.", "dns_records_name": "Název", "dns_records_status": "Současný stav", "dns_records_type": "Typ", diff --git a/data/web/lang/lang.da-dk.json b/data/web/lang/lang.da-dk.json index 33629bbe..95db916e 100644 --- a/data/web/lang/lang.da-dk.json +++ b/data/web/lang/lang.da-dk.json @@ -459,7 +459,7 @@ "cname_from_a": "Værdi afledt af A / AAAA-post. Dette understøttes, så længe posten peger på den korrekte ressource.", "dns_records": "DNS-poster", "dns_records_24hours": "Bemærk, at ændringer, der foretages i DNS, kan tage op til 24 timer for at få deres aktuelle status korrekt reflekteret på denne side. Det er beregnet som en måde for dig let at se, hvordan du konfigurerer dine DNS-poster og kontrollere, om alle dine poster er korrekt gemt i DNS.", - "dns_records_docs": "Se også dokumentationen.", + "dns_records_docs": "Se også dokumentationen.", "dns_records_data": "Korrekte data", "dns_records_name": "Navn", "dns_records_status": "Nuværende tilstand", diff --git a/data/web/lang/lang.de-de.json b/data/web/lang/lang.de-de.json index ddadfac6..73d02bdd 100644 --- a/data/web/lang/lang.de-de.json +++ b/data/web/lang/lang.de-de.json @@ -556,7 +556,7 @@ "dns_records": "DNS-Einträge", "dns_records_24hours": "Bitte beachten Sie, dass es bis zu 24 Stunden dauern kann, bis Änderungen an Ihren DNS-Einträgen als aktueller Status auf dieser Seite dargestellt werden. Diese Seite ist nur als Hilfsmittel gedacht, um die korrekten Werte für DNS-Einträge anzuzeigen und zu überprüfen, ob die Daten im DNS hinterlegt sind.", "dns_records_data": "Korrekte Daten", - "dns_records_docs": "Die Online-Dokumentation enthält weitere Informationen zur DNS-Konfiguration.", + "dns_records_docs": "Die Online-Dokumentation enthält weitere Informationen zur DNS-Konfiguration.", "dns_records_name": "Name", "dns_records_status": "Aktueller Status", "dns_records_type": "Typ", diff --git a/data/web/lang/lang.en-gb.json b/data/web/lang/lang.en-gb.json index ec97d0ae..e413664f 100644 --- a/data/web/lang/lang.en-gb.json +++ b/data/web/lang/lang.en-gb.json @@ -556,7 +556,7 @@ "dns_records": "DNS Records", "dns_records_24hours": "Please note that changes made to DNS may take up to 24 hours to correctly have their current state reflected on this page. It is intended as a way for you to easily see how to configure your DNS records and to check whether all your records are correctly stored in DNS.", "dns_records_data": "Correct Data", - "dns_records_docs": "Please also consult the documentation.", + "dns_records_docs": "Please also consult the documentation.", "dns_records_name": "Name", "dns_records_status": "Current State", "dns_records_type": "Type", diff --git a/data/web/lang/lang.fr-fr.json b/data/web/lang/lang.fr-fr.json index 96e1aef7..4b5ab2e5 100644 --- a/data/web/lang/lang.fr-fr.json +++ b/data/web/lang/lang.fr-fr.json @@ -483,7 +483,7 @@ "cname_from_a": "Valeur dérivée de l’enregistrement A/AAAA. Ceci est supporté tant que l’enregistrement indique la bonne ressource.", "dns_records": "Enregistrements DNS", "dns_records_24hours": "Veuillez noter que les modifications apportées au DNS peuvent prendre jusqu’à 24 heures pour que leurs états actuels soient correctement reflétés sur cette page. Il est conçu comme un moyen pour vous de voir facilement comment configurer vos enregistrements DNS et de vérifier si tous vos enregistrements sont correctement stockés dans les DNS.", - "dns_records_docs": "Veuillez également consulter la documentation.", + "dns_records_docs": "Veuillez également consulter la documentation.", "dns_records_data": "Données correcte", "dns_records_name": "Nom", "dns_records_status": "Etat courant", diff --git a/data/web/lang/lang.it-it.json b/data/web/lang/lang.it-it.json index 6783dfed..158f7986 100644 --- a/data/web/lang/lang.it-it.json +++ b/data/web/lang/lang.it-it.json @@ -506,7 +506,7 @@ "dns_records": "Record DNS", "dns_records_24hours": "Tieni presente che le modifiche apportate ai record DNS potrebbero richiedere fino a 24 ore per poter essere visualizzate correttamente in questa pagina. Tutto ciò è da intendersi come un modo per voi di vedere come configurare i record DNS e per controllare se tutti i record DNS sono stati inseriti correttamente.", "dns_records_data": "Dati corretti", - "dns_records_docs": "Si prega di consultare anche la documentazione.", + "dns_records_docs": "Si prega di consultare anche la documentazione.", "dns_records_name": "Nome", "dns_records_status": "Stato attuale", "dns_records_type": "Tipo", diff --git a/data/web/lang/lang.nl-nl.json b/data/web/lang/lang.nl-nl.json index efffa1d7..46325eff 100644 --- a/data/web/lang/lang.nl-nl.json +++ b/data/web/lang/lang.nl-nl.json @@ -510,7 +510,7 @@ "cname_from_a": "Waarde afgeleid van een A- of AAAA-vermelding.", "dns_records": "DNS-configuratie", "dns_records_24hours": "Houd er rekening mee dat wijzigingen aan DNS tot wel 24 uur in beslag kunnen nemen voordat ze op deze pagina worden weergegeven. Deze informatie is bedoeld om gemakkelijk te bekijken of de DNS-configuratie aan de eisen voldoet.", - "dns_records_docs": "Raadpleeg ook de documentatie.", + "dns_records_docs": "Raadpleeg ook de documentatie.", "dns_records_data": "Correcte gegevens", "dns_records_name": "Naam", "dns_records_status": "Huidige staat", diff --git a/data/web/lang/lang.pt-br.json b/data/web/lang/lang.pt-br.json index 9acaf87c..fbc79bde 100644 --- a/data/web/lang/lang.pt-br.json +++ b/data/web/lang/lang.pt-br.json @@ -554,7 +554,7 @@ "dns_records": "Registros DNS", "dns_records_24hours": "Observe que as alterações feitas no DNS podem levar até 24 horas para que seu estado atual seja refletido corretamente nesta página. O objetivo é uma forma de você ver facilmente como configurar seus registros DNS e verificar se todos os seus registros estão armazenados corretamente no DNS.", "dns_records_data": "Dados corretos", - "dns_records_docs": "Consulte também a documentação.", + "dns_records_docs": "Consulte também a documentação.", "dns_records_name": "Nome", "dns_records_status": "Estado atual", "dns_records_type": "Tipo", diff --git a/data/web/lang/lang.ro-ro.json b/data/web/lang/lang.ro-ro.json index 5c7b29b0..90c96c21 100644 --- a/data/web/lang/lang.ro-ro.json +++ b/data/web/lang/lang.ro-ro.json @@ -504,7 +504,7 @@ "cname_from_a": "Valoare derivată din înregistrarea A/AAAA. Acest lucru este acceptat atâta timp cât înregistrarea indică resursele corecte.", "dns_records": "Înregistrări DNS", "dns_records_24hours": "Rețineți că modificările aduse DNS-ului pot dura până la 24 de ore pentru a reflecta corect starea lor curentă pe această pagină. Acest mecanism este conceput ca o modalitate să vezi ușor cum să îți configurezi înregistrările DNS și să verifici dacă toate înregistrările sunt stocate corect în DNS.", - "dns_records_docs": "Vă rugăm să consultați și documentația.", + "dns_records_docs": "Vă rugăm să consultați și documentația.", "dns_records_data": "Date corecte", "dns_records_name": "Nume", "dns_records_status": "Stare curentă", diff --git a/data/web/lang/lang.ru-ru.json b/data/web/lang/lang.ru-ru.json index 2a959ab3..993f7865 100644 --- a/data/web/lang/lang.ru-ru.json +++ b/data/web/lang/lang.ru-ru.json @@ -504,7 +504,7 @@ "dns_records": "Записи DNS", "dns_records_24hours": "Обратите внимание, что для внесения изменений в DNS может потребоваться до 24 часов, чтобы правильно отобразить их текущее состояние на этой странице. Эта страница предназначен для того, чтобы вы могли легко увидеть, как настроить записи DNS и проверить, все ли записи правильно занесены в DNS.", "dns_records_data": "Значение", - "dns_records_docs": "Пожалуйста, ознакомьтесь с документацией.", + "dns_records_docs": "Пожалуйста, ознакомьтесь с документацией.", "dns_records_name": "Название", "dns_records_status": "Статус", "dns_records_type": "Тип", diff --git a/data/web/lang/lang.si-si.json b/data/web/lang/lang.si-si.json index cf1cf799..3a424631 100644 --- a/data/web/lang/lang.si-si.json +++ b/data/web/lang/lang.si-si.json @@ -543,7 +543,7 @@ "dns_records": "DNS zapisi", "dns_records_24hours": "Prosim upoštevajte, da lahko traja do 24 ur da se spremembe v DNS pravilno prikažejo na tej strani. Namen je da lahko enostavno vidite, kako konfigurirati svoje DNS zapise in preverite ali so vaši zapisi pravilno shranjeni v DNS.", "dns_records_data": "Pravilni podatki", - "dns_records_docs": "Prosim preverite tudi dokumentacijo.", + "dns_records_docs": "Prosim preverite tudi dokumentacijo.", "dns_records_name": "Ime", "dns_records_status": "Trenutno stanje", "dns_records_type": "Vrsta", diff --git a/data/web/lang/lang.sk-sk.json b/data/web/lang/lang.sk-sk.json index d656a2cd..466afdb8 100644 --- a/data/web/lang/lang.sk-sk.json +++ b/data/web/lang/lang.sk-sk.json @@ -523,7 +523,7 @@ "dns_records": "DNS záznamy", "dns_records_24hours": "Berte prosím do úvahy, že zmeny v DNS môžu trvať až 24 hodín, aby sa zmeny prejavili na tejto stránke. Pre jednoduchosť DNS konfigurácie môžete použiť údaje uvedené nižšie, prípadne skontrolovať tak správnosť záznamov v DNS.", "dns_records_data": "Správne dáta", - "dns_records_docs": "Pozrite si prosím dokumentáciu.", + "dns_records_docs": "Pozrite si prosím dokumentáciu.", "dns_records_name": "Meno", "dns_records_status": "Súčasný stav", "dns_records_type": "Typ", diff --git a/data/web/lang/lang.sv-se.json b/data/web/lang/lang.sv-se.json index ba97e705..a9870819 100644 --- a/data/web/lang/lang.sv-se.json +++ b/data/web/lang/lang.sv-se.json @@ -473,7 +473,7 @@ "cname_from_a": "Värde härstammar från A/AAAA-uppslaget. Detta stöds så länge som uppslaget pekar mot rätt resurs.", "dns_records": "DNS-uppslag", "dns_records_24hours": "Observera att ändringar gjorda i DNS kan ta upp till 24 timmar innan det visas korrekt på denna sida. Syftet med sidan är att enkelt se hur DNS-uppslagen är konfigurerade. Det är lätt att kontrollera att DNS-uppslagen är korrekt uppsatta.", - "dns_records_docs": "Se även dokumentationen.", + "dns_records_docs": "Se även dokumentationen.", "dns_records_data": "Korrektdata", "dns_records_name": "Namn", "dns_records_status": "Nuvarande status", diff --git a/data/web/lang/lang.uk-ua.json b/data/web/lang/lang.uk-ua.json index e778f156..201a60b4 100644 --- a/data/web/lang/lang.uk-ua.json +++ b/data/web/lang/lang.uk-ua.json @@ -525,7 +525,7 @@ "cname_from_a": "Значення, отримане із запису A/AAAA. Це підтримується, поки запис вказує на правильний ресурс.", "dns_records": "Записи DNS", "dns_records_data": "Значення", - "dns_records_docs": "Також перегляньте документацію.", + "dns_records_docs": "Також перегляньте документацію.", "dns_records_name": "Назва", "dns_records_status": "Статус", "optional": "Цей запис необов'язковий.", diff --git a/data/web/lang/lang.zh-cn.json b/data/web/lang/lang.zh-cn.json index b1aacf5c..cca5ecc5 100644 --- a/data/web/lang/lang.zh-cn.json +++ b/data/web/lang/lang.zh-cn.json @@ -494,7 +494,7 @@ "dns_records": "DNS 记录", "dns_records_24hours": "请注意 DNS 记录的更改可能需要24小时才可以使此页面的当前状态显示正确。此页面为你提供了一个可以便捷查询如何配置 DNS 记录以及检查你的 DNS 记录是否正确的方式。", "dns_records_data": "正确数据", - "dns_records_docs": "请同时也参考这个文档.", + "dns_records_docs": "请同时也参考这个文档.", "dns_records_name": "名称", "dns_records_status": "当前状态", "dns_records_type": "类型", diff --git a/data/web/lang/lang.zh-tw.json b/data/web/lang/lang.zh-tw.json index 4d84b211..332eabb6 100644 --- a/data/web/lang/lang.zh-tw.json +++ b/data/web/lang/lang.zh-tw.json @@ -526,7 +526,7 @@ "dns_records": "DNS 紀錄", "dns_records_24hours": "請注意 DNS 紀錄的更改可能需要 24 小時才能正確顯示於此頁面。此頁面的目的是為了讓你可以輕鬆的了解如何設定 DNS 紀錄並檢查 DNS 是否設定正確。", "dns_records_data": "正確值", - "dns_records_docs": "請同時另外查看 文件.", + "dns_records_docs": "請同時另外查看 文件.", "dns_records_name": "名稱", "dns_records_status": "目前狀態", "dns_records_type": "類型", From 86ba019ca09b7e09c59ec8a1e4f562493947510a Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Fri, 9 Feb 2024 14:59:14 +0100 Subject: [PATCH 004/138] [Rspamd] apply domain wide footer to alias domains --- data/conf/rspamd/dynmaps/footer.php | 25 +++++++++- data/web/edit.php | 3 +- data/web/inc/functions.mailbox.inc.php | 65 ++++++++++++++++++-------- data/web/inc/init_db.inc.php | 3 +- data/web/lang/lang.de-de.json | 2 +- data/web/lang/lang.en-gb.json | 2 +- data/web/lang/lang.pt-br.json | 4 +- data/web/lang/lang.ru-ru.json | 2 +- data/web/lang/lang.uk-ua.json | 4 +- data/web/lang/lang.zh-tw.json | 2 +- data/web/templates/edit/domain.twig | 9 +++- 11 files changed, 87 insertions(+), 34 deletions(-) diff --git a/data/conf/rspamd/dynmaps/footer.php b/data/conf/rspamd/dynmaps/footer.php index 36b307c1..545c45ec 100644 --- a/data/conf/rspamd/dynmaps/footer.php +++ b/data/conf/rspamd/dynmaps/footer.php @@ -56,21 +56,42 @@ $empty_footer = json_encode(array( error_log("FOOTER: checking for domain " . $domain . ", user " . $username . " and address " . $from . PHP_EOL); try { - $stmt = $pdo->prepare("SELECT `plain`, `html`, `mbox_exclude`, `skip_replies` FROM `domain_wide_footer` + // try get $target_domain if $domain is an alias_domain + $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain` + WHERE `alias_domain` = :alias_domain"); + $stmt->execute(array( + ':alias_domain' => $domain + )); + $alias_domain = $stmt->fetch(PDO::FETCH_ASSOC); + if (!$alias_domain) { + $target_domain = $domain; + } else { + $target_domain = $alias_domain['target_domain']; + } + + // get footer associated with the domain + $stmt = $pdo->prepare("SELECT `plain`, `html`, `mbox_exclude`, `alias_domain_exclude`, `skip_replies` FROM `domain_wide_footer` WHERE `domain` = :domain"); $stmt->execute(array( - ':domain' => $domain + ':domain' => $target_domain )); $footer = $stmt->fetch(PDO::FETCH_ASSOC); + + // check if the sender is excluded if (in_array($from, json_decode($footer['mbox_exclude']))){ $footer = false; } + if (in_array($domain, json_decode($footer['alias_domain_exclude']))){ + $footer = false; + } if (empty($footer)){ echo $empty_footer; exit; } error_log("FOOTER: " . json_encode($footer) . PHP_EOL); + // footer will be applied + // get custom mailbox attributes to insert into the footer $stmt = $pdo->prepare("SELECT `custom_attributes` FROM `mailbox` WHERE `username` = :username"); $stmt->execute(array( ':username' => $username diff --git a/data/web/edit.php b/data/web/edit.php index 83ae1467..4c5cd89e 100644 --- a/data/web/edit.php +++ b/data/web/edit.php @@ -59,7 +59,8 @@ if (isset($_SESSION['mailcow_cc_role'])) { 'domain_details' => $result, 'domain_footer' => $domain_footer, 'mailboxes' => mailbox('get', 'mailboxes', $_GET["domain"]), - 'aliases' => mailbox('get', 'aliases', $_GET["domain"], 'address') + 'aliases' => mailbox('get', 'aliases', $_GET["domain"], 'address'), + 'alias_domains' => mailbox('get', 'alias_domains', $_GET["domain"]) ]; } } diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 0f48efbd..ea242cf8 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -3438,30 +3438,54 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $footers['plain'] = isset($_data['plain']) ? $_data['plain'] : ''; $footers['skip_replies'] = isset($_data['skip_replies']) ? (int)$_data['skip_replies'] : 0; $footers['mbox_exclude'] = array(); - if (isset($_data["mbox_exclude"])){ - if (!is_array($_data["mbox_exclude"])) { - $_data["mbox_exclude"] = array($_data["mbox_exclude"]); + $footers['alias_domain_exclude'] = array(); + if (isset($_data["exclude"])){ + if (!is_array($_data["exclude"])) { + $_data["exclude"] = array($_data["exclude"]); } - foreach ($_data["mbox_exclude"] as $mailbox) { - if (!filter_var($mailbox, FILTER_VALIDATE_EMAIL)) { + foreach ($_data["exclude"] as $exclude) { + if (filter_var($exclude, FILTER_VALIDATE_EMAIL)) { + $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `address` = :address + UNION + SELECT `username` FROM `mailbox` WHERE `username` = :username"); + $stmt->execute(array( + ':address' => $exclude, + ':username' => $exclude, + )); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + if(!$row){ + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => array('username_invalid', $exclude) + ); + continue; + } + array_push($footers['mbox_exclude'], $exclude); + } + elseif (is_valid_domain_name($exclude)) { + $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `alias_domain` = :alias_domain"); + $stmt->execute(array( + ':alias_domain' => $exclude, + )); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + if(!$row){ + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => array('username_invalid', $exclude) + ); + continue; + } + array_push($footers['alias_domain_exclude'], $exclude); + } + else { $_SESSION['return'][] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), - 'msg' => array('username_invalid', $mailbox) + 'msg' => array('username_invalid', $exclude) ); - continue; } - $is_now = mailbox('get', 'mailbox_details', $mailbox); - if(empty($is_now)){ - $_SESSION['return'][] = array( - 'type' => 'danger', - 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), - 'msg' => array('username_invalid', $mailbox) - ); - continue; - } - - array_push($footers['mbox_exclude'], $mailbox); } } foreach ($domains as $domain) { @@ -3486,12 +3510,13 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { try { $stmt = $pdo->prepare("DELETE FROM `domain_wide_footer` WHERE `domain`= :domain"); $stmt->execute(array(':domain' => $domain)); - $stmt = $pdo->prepare("INSERT INTO `domain_wide_footer` (`domain`, `html`, `plain`, `mbox_exclude`, `skip_replies`) VALUES (:domain, :html, :plain, :mbox_exclude, :skip_replies)"); + $stmt = $pdo->prepare("INSERT INTO `domain_wide_footer` (`domain`, `html`, `plain`, `mbox_exclude`, `alias_domain_exclude`, `skip_replies`) VALUES (:domain, :html, :plain, :mbox_exclude, :alias_domain_exclude, :skip_replies)"); $stmt->execute(array( ':domain' => $domain, ':html' => $footers['html'], ':plain' => $footers['plain'], ':mbox_exclude' => json_encode($footers['mbox_exclude']), + ':alias_domain_exclude' => json_encode($footers['alias_domain_exclude']), ':skip_replies' => $footers['skip_replies'], )); } @@ -4648,7 +4673,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { } try { - $stmt = $pdo->prepare("SELECT `html`, `plain`, `mbox_exclude`, `skip_replies` FROM `domain_wide_footer` + $stmt = $pdo->prepare("SELECT `html`, `plain`, `mbox_exclude`, `alias_domain_exclude`, `skip_replies` FROM `domain_wide_footer` WHERE `domain` = :domain"); $stmt->execute(array( ':domain' => $domain diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index 6fec0c2f..445af8a9 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 = "08012024_1442"; + $db_version = "09022024_1433"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -273,6 +273,7 @@ function init_db_schema() { "html" => "LONGTEXT", "plain" => "LONGTEXT", "mbox_exclude" => "JSON NOT NULL DEFAULT ('[]')", + "alias_domain_exclude" => "JSON NOT NULL DEFAULT ('[]')", "skip_replies" => "TINYINT(1) NOT NULL DEFAULT '0'" ), "keys" => array( diff --git a/data/web/lang/lang.de-de.json b/data/web/lang/lang.de-de.json index 73d02bdd..2298e1cb 100644 --- a/data/web/lang/lang.de-de.json +++ b/data/web/lang/lang.de-de.json @@ -613,6 +613,7 @@ "extended_sender_acl_info": "Der DKIM-Domainkey der externen Absenderdomain sollte in diesen Server importiert werden, falls vorhanden.
\r\n Wird SPF verwendet, muss diesem Server der Versand gestattet werden.
\r\n Wird eine Domain oder Alias-Domain zu diesem Server hinzugefügt, die sich mit der externen Absenderadresse überschneidet, wird der externe Absender hier entfernt.
\r\n Ein Eintrag @domain.tld erlaubt den Versand als *@domain.tld", "force_pw_update": "Erzwinge Passwortänderung bei nächstem Login", "force_pw_update_info": "Dem Benutzer wird lediglich der Zugang zur %s ermöglicht, App Passwörter funktionieren weiterhin.", + "footer_exclude": "von Fußzeile ausschließen", "full_name": "Voller Name", "gal": "Globales Adressbuch", "gal_info": "Das globale Adressbuch enthält alle Objekte einer Domain und kann durch keinen Benutzer geändert werden. Die Verfügbarkeitsinformation in SOGo ist nur bei eingeschaltetem globalen Adressbuch ersichtlich Zum Anwenden einer Änderung muss SOGo neugestartet werden.", @@ -631,7 +632,6 @@ "max_quota": "Max. Größe per Mailbox (MiB)", "maxage": "Maximales Alter in Tagen einer Nachricht, die kopiert werden soll
(0 = alle Nachrichten kopieren)", "maxbytespersecond": "Max. Übertragungsrate in Bytes/s (0 für unlimitiert)", - "mbox_exclude": "Mailboxen ausschließen", "mbox_rl_info": "Dieses Limit wird auf den SASL Loginnamen angewendet und betrifft daher alle Absenderadressen, die der eingeloggte Benutzer verwendet. Bei Mailbox Ratelimit überwiegt ein Domain-weites Ratelimit.", "mins_interval": "Intervall (min)", "multiple_bookings": "Mehrfaches Buchen", diff --git a/data/web/lang/lang.en-gb.json b/data/web/lang/lang.en-gb.json index e413664f..964caade 100644 --- a/data/web/lang/lang.en-gb.json +++ b/data/web/lang/lang.en-gb.json @@ -613,6 +613,7 @@ "extended_sender_acl_info": "A DKIM domain key should be imported, if available.
\r\n Remember to add this server to the corresponding SPF TXT record.
\r\n Whenever a domain or alias domain is added to this server, that overlaps with an external address, the external address is removed.
\r\n Use @domain.tld to allow to send as *@domain.tld.", "force_pw_update": "Force password update at next login", "force_pw_update_info": "This user will only be able to login to %s. App passwords remain useable.", + "footer_exclude": "Exclude from footer", "full_name": "Full name", "gal": "Global Address List", "gal_info": "The GAL contains all objects of a domain and cannot be edited by any user. Free/busy information in SOGo is missing, if disabled! Restart SOGo to apply changes.", @@ -631,7 +632,6 @@ "max_quota": "Max. quota per mailbox (MiB)", "maxage": "Maximum age of messages in days that will be polled from remote
(0 = ignore age)", "maxbytespersecond": "Max. bytes per second
(0 = unlimited)", - "mbox_exclude": "Exclude mailboxes", "mbox_rl_info": "This rate limit is applied on the SASL login name, it matches any \"from\" address used by the logged-in user. A mailbox rate limit overrides a domain-wide rate limit.", "mins_interval": "Interval (min)", "multiple_bookings": "Multiple bookings", diff --git a/data/web/lang/lang.pt-br.json b/data/web/lang/lang.pt-br.json index fbc79bde..5636f5cd 100644 --- a/data/web/lang/lang.pt-br.json +++ b/data/web/lang/lang.pt-br.json @@ -609,6 +609,7 @@ "extended_sender_acl_info": "Uma chave de domínio DKIM deve ser importada, se disponível.
\r\n Lembre-se de adicionar esse servidor ao registro TXT SPF correspondente.
\r\n Sempre que um domínio ou domínio de alias é adicionado a esse servidor, que se sobrepõe a um endereço externo, o endereço externo é removido.
\r\n Use @domain .tld para permitir o envio como * @domain .tld.", "force_pw_update": "Forçar a atualização da senha no próximo login", "force_pw_update_info": "Esse usuário só poderá fazer login em %s. As senhas do aplicativo permanecem utilizáveis.", + "footer_exclude": "Excluir do rodapé", "full_name": "Nome completo", "gal": "Lista de endereços global", "gal_info": "A GAL contém todos os objetos de um domínio e não pode ser editada por nenhum usuário. Faltam informações de disponibilidade no SoGo, se desativadas! Reinicie o SoGo para aplicar as alterações.", @@ -687,8 +688,7 @@ "unchanged_if_empty": "Se inalterado, deixe em branco", "username": "Nome de usuário", "validate_save": "Valide e salve", - "custom_attributes": "Atributos personalizados", - "mbox_exclude": "Excluir mailboxes" + "custom_attributes": "Atributos personalizados" }, "fido2": { "confirm": "Confirme", diff --git a/data/web/lang/lang.ru-ru.json b/data/web/lang/lang.ru-ru.json index 993f7865..5891b6ab 100644 --- a/data/web/lang/lang.ru-ru.json +++ b/data/web/lang/lang.ru-ru.json @@ -546,6 +546,7 @@ "extended_sender_acl_info": "Для внешних доменов должен быть импортирован или сгенерирован доменный ключ DKIM с соответствующей записью TXT в домене, если внешний домен использует DMARC.
\r\n Не забудьте добавить этот сервер к соответствующей записи SPF TXT внешнего домена.
\r\n Добавление домена из списка внешних адресов в mailcow автоматически удалит соответствующие записи из внешних адресов пользователей.
\r\n Чтобы разрешить пользователю отправку от имени *@domain.tld, укажите @domain.tld.", "force_pw_update": "Требовать смены пароля при следующем входе в систему", "force_pw_update_info": "Пользователь должен будет войти в %s и сменить свой пароль. mailcow OAuth2, SOGo, EAS, IMAP/POP3 и SMTP будут не доступны до смены пароля.", + "footer_exclude": "Исключить из нижнего колонтитула", "full_name": "Полное имя", "gal": "GAL - Глобальная адресная книга", "gal_info": "GAL содержит все объекты домена и не подлежит редактированию. Информация о занятости в SOGo будет отсутствовать для домена, если данная функция будет отключена! Требуется перезапустить SOGo, чтобы применить изменения.", @@ -635,7 +636,6 @@ "domain_footer": "Нижний колонтитул домена", "domain_footer_html": "HTML нижний колонтитул", "domain_footer_plain": "ПРОСТОЙ нижний колонтитул", - "mbox_exclude": "Исключить почтовые ящики", "custom_attributes": "Пользовательские атрибуты" }, "fido2": { diff --git a/data/web/lang/lang.uk-ua.json b/data/web/lang/lang.uk-ua.json index 201a60b4..73122464 100644 --- a/data/web/lang/lang.uk-ua.json +++ b/data/web/lang/lang.uk-ua.json @@ -561,6 +561,7 @@ "extended_sender_acl": "Зовнішні адреси пошти", "force_pw_update": "Вимагати зміну пароля при наступному вході до системи", "force_pw_update_info": "Цей користувач зможе увійти лише в %s. Паролі додатків залишаються придатними для використання.", + "footer_exclude": "Виключити з нижнього колонтитула", "full_name": "Повне ім'я", "gal": "GAL - Глобальна адресна книга", "generate": "згенерувати", @@ -659,8 +660,7 @@ }, "domain_footer_html": "Нижній колонтитул HTML", "domain_footer_plain": "ЗВИЧАЙНИЙ нижній колонтитул", - "custom_attributes": "Користувацькі атрибути", - "mbox_exclude": "Виключити поштові скриньки" + "custom_attributes": "Користувацькі атрибути" }, "fido2": { "confirm": "Підтвердити", diff --git a/data/web/lang/lang.zh-tw.json b/data/web/lang/lang.zh-tw.json index 332eabb6..af2fb557 100644 --- a/data/web/lang/lang.zh-tw.json +++ b/data/web/lang/lang.zh-tw.json @@ -569,6 +569,7 @@ "extended_sender_acl_info": "如果可以的話,請匯入 DKIM 域名金鑰。
\r\n別忘記將此伺服器新增到相應的 SPF TXT 中。
\r\n當域名或域名別名被新增時,若其與此外部寄件人地址交疊,則外部寄件人地址會被移除。
\r\n填入 @domain.tld 以允許作為 *@domain.tld 發送郵件。", "force_pw_update": "在下一次登入時強制要求更新密碼", "force_pw_update_info": "此使用者只能登入至 %s。應用程式密碼仍可正常使用", + "footer_exclude": "从页脚排除", "full_name": "全名", "gal": "全域聯絡人清單", "gal_info": "全域聯絡人清單包含了域名下的所有物件,且使用者不可編輯。如果關閉,使用者的 空閒/繁忙 訊息將不能在 SOGo 中顯示。重新啟動 SOGo 以應用更改。", @@ -648,7 +649,6 @@ "validate_save": "驗證並儲存", "domain_footer_info": "網域範圍的頁尾將會新增至與該網域內的位址關聯的所有外發電子郵件。
以下變數可用於頁尾:", "custom_attributes": "自訂屬性", - "mbox_exclude": "排除信箱", "pushover_sound": "聲音" }, "fido2": { diff --git a/data/web/templates/edit/domain.twig b/data/web/templates/edit/domain.twig index 8a700d06..08d031c3 100644 --- a/data/web/templates/edit/domain.twig +++ b/data/web/templates/edit/domain.twig @@ -289,9 +289,9 @@ {{ lang.edit.domain_footer_info_vars.custom }}
- +
- {% for mailbox in mailboxes %} {% endfor %} + {% for alias_domain in alias_domains %} + + {% endfor %}
From a0e55cb9b17933f355bbaf773295a2592c950211 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Fri, 9 Feb 2024 15:08:21 +0100 Subject: [PATCH 005/138] [Web] fix blank /debug page with invalid timezone --- data/web/debug.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/data/web/debug.php b/data/web/debug.php index 52052f68..9c338009 100644 --- a/data/web/debug.php +++ b/data/web/debug.php @@ -39,9 +39,13 @@ foreach ($containers as $container => $container_info) { $StartedAt['month'], $StartedAt['day'], $StartedAt['year'])); - $user_tz = new DateTimeZone(getenv('TZ')); - $date->setTimezone($user_tz); - $started = $date->format('r'); + try { + $user_tz = new DateTimeZone(getenv('TZ')); + $date->setTimezone($user_tz); + $started = $date->format('r'); + } catch(Exception $e) { + $started = '?'; + } } else { $started = '?'; From 288dbfa37c59666e548915e66cd0cd3902f08eed Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Fri, 9 Feb 2024 15:13:45 +0100 Subject: [PATCH 006/138] [Web] display human readable domainnames instead of punycode --- data/web/inc/functions.mailbox.inc.php | 1 + data/web/js/site/mailbox.js | 12 ++++++++---- data/web/templates/edit/domain.twig | 9 +++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 0f48efbd..cf2e567e 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -4316,6 +4316,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $domaindata['mboxes_in_domain'] = $MailboxDataDomain['count']; $domaindata['mboxes_left'] = $row['mailboxes'] - $MailboxDataDomain['count']; $domaindata['domain_name'] = $row['domain']; + $domaindata['domain_h_name'] = idn_to_utf8($row['domain']); $domaindata['description'] = $row['description']; $domaindata['max_num_aliases_for_domain'] = $row['aliases']; $domaindata['max_num_mboxes_for_domain'] = $row['mailboxes']; diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js index cc316b71..e2016e3e 100644 --- a/data/web/js/site/mailbox.js +++ b/data/web/js/site/mailbox.js @@ -451,6 +451,10 @@ jQuery(function($){ dataSrc: function(json){ $.each(json.data, function(i, item) { item.domain_name = escapeHtml(item.domain_name); + item.domain_h_name = escapeHtml(item.domain_h_name); + if (item.domain_name != item.domain_h_name){ + item.domain_h_name = item.domain_h_name + '' + item.domain_name + ''; + } item.aliases = item.aliases_in_domain + " / " + item.max_num_aliases_for_domain; item.mailboxes = item.mboxes_in_domain + " / " + item.max_num_mboxes_for_domain; @@ -489,11 +493,11 @@ jQuery(function($){ if (item.backupmx == 1) { if (item.relay_unknown_only == 1) { - item.domain_name = '
Relay Non-Local
' + item.domain_name; + item.domain_h_name = '
Relay Non-Local
' + item.domain_h_name; } else if (item.relay_all_recipients == 1) { - item.domain_name = '
Relay All
' + item.domain_name; + item.domain_h_name = '
Relay All
' + item.domain_h_name; } else { - item.domain_name = '
Relay
' + item.domain_name; + item.domain_h_name = '
Relay
' + item.domain_h_name; } } }); @@ -521,7 +525,7 @@ jQuery(function($){ }, { title: lang.domain, - data: 'domain_name', + data: 'domain_h_name', responsivePriority: 3, defaultContent: '' }, diff --git a/data/web/templates/edit/domain.twig b/data/web/templates/edit/domain.twig index 8a700d06..8d5c7904 100644 --- a/data/web/templates/edit/domain.twig +++ b/data/web/templates/edit/domain.twig @@ -26,6 +26,15 @@ +
+ +
+ {{ result.domain_h_name }} + {% if result.domain_h_name != result.domain_name %} + {{ result.domain_name }} + {% endif %} +
+
From dac1bd88dc2842317fefb22b0efb0c8a1eb92bf4 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Fri, 9 Feb 2024 15:17:02 +0100 Subject: [PATCH 007/138] [Web] fix setting unchecked checkboxes --- data/web/templates/modals/mailbox.twig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/data/web/templates/modals/mailbox.twig b/data/web/templates/modals/mailbox.twig index 22807c8d..6316d9fb 100644 --- a/data/web/templates/modals/mailbox.twig +++ b/data/web/templates/modals/mailbox.twig @@ -381,6 +381,12 @@
+
+ +
+ + {{ lang.admin.password_reset_info }} +
+
diff --git a/data/web/templates/index.twig b/data/web/templates/index.twig index aa282547..90e232ca 100644 --- a/data/web/templates/index.twig +++ b/data/web/templates/index.twig @@ -63,6 +63,9 @@ {% endif %}
+ {% if login_delay %}

{{ lang.login.delayed|format(login_delay) }}

{% endif %} diff --git a/data/web/templates/modals/user.twig b/data/web/templates/modals/user.twig index b4188773..c9cd4b97 100644 --- a/data/web/templates/modals/user.twig +++ b/data/web/templates/modals/user.twig @@ -309,6 +309,33 @@
+ +
From c37bf0bb32aa58266d75ca84ac8f8f36f93d0939 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Wed, 31 Jul 2024 09:22:52 +0200 Subject: [PATCH 089/138] [Web] improve error handling for user password resets --- data/web/inc/functions.inc.php | 40 +++++++------------ data/web/lang/lang.de-de.json | 1 + data/web/lang/lang.en-gb.json | 1 + .../admin/tab-config-password-settings.twig | 8 ++-- 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index af74d140..562af71d 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -1137,7 +1137,7 @@ function edit_user_account($_data) { ); return false; } - + $pw_recovery_email = (!filter_var($pw_recovery_email, FILTER_VALIDATE_EMAIL)) ? '' : $pw_recovery_email; $stmt = $pdo->prepare("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.recovery_email', :recovery_email) WHERE `username` = :username"); @@ -2329,6 +2329,17 @@ function reset_password($action, $data = null) { return false; } + $pw_reset_notification = reset_password('get_notification', 'raw'); + if (!$pw_reset_notification) return false; + if (empty($pw_reset_notification['from']) || empty($pw_reset_notification['subject'])) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $action, $_data_log), + 'msg' => 'password_reset_na' + ); + return false; + } + $stmt = $pdo->prepare("SELECT * FROM `mailbox` WHERE `username` = :username"); $stmt->execute(array(':username' => $username)); @@ -2381,9 +2392,6 @@ function reset_password($action, $data = null) { ':token' => $token )); - $pw_reset_notification = reset_password('get_notification', 'raw'); - if (!$pw_reset_notification) return false; - $reset_link = getBaseURL() . "/reset-password?token=" . $token; $request_date = new DateTime(); @@ -2633,30 +2641,10 @@ function reset_password($action, $data = null) { $subject = $data['subject']; $from = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $data['from']); - if (filter_var($from, FILTER_VALIDATE_EMAIL) === false) { - $_SESSION['return'][] = array( - 'type' => 'danger', - 'log' => array(__FUNCTION__, $action, $_data_log), - 'msg' => '???' - ); - $_SESSION['return'][] = array( - 'type' => 'danger', - 'log' => array(__FUNCTION__, $action, $_data_log), - 'msg' => 'access_denied' - ); - return false; - } - + $from = (!filter_var($from, FILTER_VALIDATE_EMAIL)) ? "" : $from; + $subject = (empty($subject)) ? "" : $subject; $text = (empty($data['text_tmpl'])) ? "" : $data['text_tmpl']; $html = (empty($data['html_tmpl'])) ? "" : $data['html_tmpl']; - if (empty($text) && empty($html)) { - $_SESSION['return'][] = array( - 'type' => 'danger', - 'log' => array(__FUNCTION__, $action, $_data_log), - 'msg' => 'access_denied' - ); - return false; - } try { $redis->Set('PW_RESET_FROM', $from); diff --git a/data/web/lang/lang.de-de.json b/data/web/lang/lang.de-de.json index a734e09c..189774ee 100644 --- a/data/web/lang/lang.de-de.json +++ b/data/web/lang/lang.de-de.json @@ -446,6 +446,7 @@ "password_empty": "Passwort darf nicht leer sein", "password_mismatch": "Passwort-Wiederholung stimmt nicht überein", "password_reset_invalid_user": "Benutzer nicht gefunden oder keine E-Mail-Adresse zur Wiederherstellung eingerichtet", + "password_reset_na": "Die Passwortwiederherstellung ist momentan nicht verfügbar. Bitte wenden Sie sich an Ihren Administrator.", "policy_list_from_exists": "Ein Eintrag mit diesem Wert existiert bereits", "policy_list_from_invalid": "Eintrag hat ein ungültiges Format", "private_key_error": "Schlüsselfehler: %s", diff --git a/data/web/lang/lang.en-gb.json b/data/web/lang/lang.en-gb.json index 636c1ade..60044180 100644 --- a/data/web/lang/lang.en-gb.json +++ b/data/web/lang/lang.en-gb.json @@ -446,6 +446,7 @@ "password_empty": "Password must not be empty", "password_mismatch": "Confirmation password does not match", "password_reset_invalid_user": "Mailbox not found or no recovery email is set", + "password_reset_na": "The password recovery is currently unavailable. Please contact your administrator.", "policy_list_from_exists": "A record with given name exists", "policy_list_from_invalid": "Record has invalid format", "private_key_error": "Private key error: %s", diff --git a/data/web/templates/admin/tab-config-password-settings.twig b/data/web/templates/admin/tab-config-password-settings.twig index 6b2c494c..5998c638 100644 --- a/data/web/templates/admin/tab-config-password-settings.twig +++ b/data/web/templates/admin/tab-config-password-settings.twig @@ -57,14 +57,14 @@
- - + +
- - + +
From fbecd60e563d3e924e2c085681a5dfe976e692d9 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Wed, 31 Jul 2024 09:23:53 +0200 Subject: [PATCH 090/138] [Web] add new pw_reset acl to mailbox templates --- data/web/inc/functions.mailbox.inc.php | 12 +++++++++--- data/web/js/site/mailbox.js | 3 +++ data/web/templates/edit/mailbox-templates.twig | 1 + data/web/templates/modals/mailbox.twig | 2 ++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 7c9414f0..ffcc3820 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -184,6 +184,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { 'msg' => 'global_filter_written' ); return true; + break; case 'filter': $sieve = new Sieve\SieveParser(); if (!isset($_SESSION['acl']['filters']) || $_SESSION['acl']['filters'] != "1" ) { @@ -1249,6 +1250,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $_data['quarantine_notification'] = (in_array('quarantine_notification', $_data['acl'])) ? 1 : 0; $_data['quarantine_category'] = (in_array('quarantine_category', $_data['acl'])) ? 1 : 0; $_data['app_passwds'] = (in_array('app_passwds', $_data['acl'])) ? 1 : 0; + $_data['pw_reset'] = (in_array('pw_reset', $_data['acl'])) ? 1 : 0; } else { $_data['spam_alias'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_spam_alias']); $_data['tls_policy'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_tls_policy']); @@ -1264,14 +1266,15 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $_data['quarantine_notification'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_quarantine_notification']); $_data['quarantine_category'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_quarantine_category']); $_data['app_passwds'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_app_passwds']); + $_data['pw_reset'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_pw_reset']); } try { $stmt = $pdo->prepare("INSERT INTO `user_acl` (`username`, `spam_alias`, `tls_policy`, `spam_score`, `spam_policy`, `delimiter_action`, `syncjobs`, `eas_reset`, `sogo_profile_reset`, - `pushover`, `quarantine`, `quarantine_attachments`, `quarantine_notification`, `quarantine_category`, `app_passwds`) + `pushover`, `quarantine`, `quarantine_attachments`, `quarantine_notification`, `quarantine_category`, `app_passwds`, `pw_reset`) VALUES (:username, :spam_alias, :tls_policy, :spam_score, :spam_policy, :delimiter_action, :syncjobs, :eas_reset, :sogo_profile_reset, - :pushover, :quarantine, :quarantine_attachments, :quarantine_notification, :quarantine_category, :app_passwds) "); + :pushover, :quarantine, :quarantine_attachments, :quarantine_notification, :quarantine_category, :app_passwds, :pw_reset) "); $stmt->execute(array( ':username' => $username, ':spam_alias' => $_data['spam_alias'], @@ -1287,7 +1290,8 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ':quarantine_attachments' => $_data['quarantine_attachments'], ':quarantine_notification' => $_data['quarantine_notification'], ':quarantine_category' => $_data['quarantine_category'], - ':app_passwds' => $_data['app_passwds'] + ':app_passwds' => $_data['app_passwds'], + ':pw_reset' => $_data['pw_reset'] )); } catch (PDOException $e) { @@ -1576,6 +1580,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $attr['acl_quarantine_notification'] = (in_array('quarantine_notification', $_data['acl'])) ? 1 : 0; $attr['acl_quarantine_category'] = (in_array('quarantine_category', $_data['acl'])) ? 1 : 0; $attr['acl_app_passwds'] = (in_array('app_passwds', $_data['acl'])) ? 1 : 0; + $attr['acl_pw_reset'] = (in_array('pw_reset', $_data['acl'])) ? 1 : 0; } else { $_data['acl'] = (array)$_data['acl']; $attr['acl_spam_alias'] = 0; @@ -3276,6 +3281,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $attr['acl_quarantine_notification'] = (in_array('quarantine_notification', $_data['acl'])) ? 1 : 0; $attr['acl_quarantine_category'] = (in_array('quarantine_category', $_data['acl'])) ? 1 : 0; $attr['acl_app_passwds'] = (in_array('app_passwds', $_data['acl'])) ? 1 : 0; + $attr['acl_pw_reset'] = (in_array('pw_reset', $_data['acl'])) ? 1 : 0; } else { foreach ($is_now as $key => $value){ $attr[$key] = $is_now[$key]; diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js index e2016e3e..51dbcf43 100644 --- a/data/web/js/site/mailbox.js +++ b/data/web/js/site/mailbox.js @@ -380,6 +380,9 @@ $(document).ready(function() { if (template.acl_app_passwds == 1){ acl.push("app_passwds"); } + if (template.acl_pw_reset == 1){ + acl.push("pw_reset"); + } $('#user_acl').selectpicker('val', acl); $('#rl_value').val(template.rl_value); diff --git a/data/web/templates/edit/mailbox-templates.twig b/data/web/templates/edit/mailbox-templates.twig index f606bd45..6d150b26 100644 --- a/data/web/templates/edit/mailbox-templates.twig +++ b/data/web/templates/edit/mailbox-templates.twig @@ -112,6 +112,7 @@ + diff --git a/data/web/templates/modals/mailbox.twig b/data/web/templates/modals/mailbox.twig index 6316d9fb..0f1b23a7 100644 --- a/data/web/templates/modals/mailbox.twig +++ b/data/web/templates/modals/mailbox.twig @@ -149,6 +149,7 @@ + @@ -318,6 +319,7 @@ + From ff34eb12e2dbd9f9905aba0020fcb5921c2be7a0 Mon Sep 17 00:00:00 2001 From: milkmaker Date: Thu, 1 Aug 2024 00:16:46 +0000 Subject: [PATCH 091/138] update postscreen_access.cidr --- data/conf/postfix/postscreen_access.cidr | 55 ++++-------------------- 1 file changed, 8 insertions(+), 47 deletions(-) diff --git a/data/conf/postfix/postscreen_access.cidr b/data/conf/postfix/postscreen_access.cidr index e24e0fa7..78ffc3a8 100644 --- a/data/conf/postfix/postscreen_access.cidr +++ b/data/conf/postfix/postscreen_access.cidr @@ -1,6 +1,6 @@ -# Whitelist generated by Postwhite v3.4 on Mon Jul 1 00:16:55 UTC 2024 +# Whitelist generated by Postwhite v3.4 on Thu Aug 1 00:16:45 UTC 2024 # https://github.com/stevejenkins/postwhite/ -# 1993 total rules +# 1954 total rules 2a00:1450:4000::/36 permit 2a01:111:f400::/48 permit 2a01:111:f403:8000::/50 permit @@ -19,11 +19,8 @@ 8.20.114.31 permit 8.25.194.0/23 permit 8.25.196.0/23 permit -8.39.54.0/23 permit -8.40.222.0/23 permit 10.162.0.0/16 permit 12.130.86.238 permit -13.72.50.45 permit 13.110.208.0/21 permit 13.110.209.0/24 permit 13.110.216.0/22 permit @@ -44,6 +41,7 @@ 18.198.96.88 permit 18.208.124.128/25 permit 18.216.232.154 permit +18.235.27.253 permit 18.236.40.242 permit 18.236.56.161 permit 20.51.6.32/30 permit @@ -66,7 +64,6 @@ 20.112.250.133 permit 20.118.139.208/30 permit 20.141.10.196 permit -20.185.213.0/24 permit 20.185.214.0/27 permit 20.185.214.32/27 permit 20.185.214.64/27 permit @@ -112,13 +109,13 @@ 37.218.249.47 permit 37.218.251.62 permit 39.156.163.64/29 permit -40.71.187.0/24 permit 40.92.0.0/15 permit 40.92.0.0/16 permit 40.107.0.0/16 permit 40.112.65.63 permit 43.228.184.0/22 permit 44.206.138.57 permit +44.217.45.156 permit 44.236.56.93 permit 44.238.220.251 permit 46.19.170.16 permit @@ -181,6 +178,7 @@ 50.18.125.237 permit 50.18.126.162 permit 50.31.32.0/19 permit +50.31.36.205 permit 50.56.130.220/30 permit 52.1.14.157 permit 52.5.230.59 permit @@ -202,7 +200,6 @@ 52.96.91.34 permit 52.96.111.82 permit 52.96.172.98 permit -52.96.214.50 permit 52.96.222.194 permit 52.96.222.226 permit 52.96.223.2 permit @@ -223,10 +220,6 @@ 52.234.172.96/28 permit 52.235.253.128 permit 52.236.28.240/28 permit -52.244.206.214 permit -52.247.53.144 permit -52.250.107.196 permit -52.250.126.174 permit 54.90.148.255 permit 54.165.19.38 permit 54.172.97.247 permit @@ -331,7 +324,6 @@ 65.110.161.77 permit 65.123.29.213 permit 65.123.29.220 permit -65.154.166.0/24 permit 65.212.180.36 permit 66.102.0.0/20 permit 66.119.150.192/26 permit @@ -450,7 +442,6 @@ 69.171.232.0/24 permit 69.171.244.0/23 permit 70.37.151.128/25 permit -70.42.149.0/24 permit 70.42.149.35 permit 72.14.192.0/18 permit 72.21.192.0/19 permit @@ -567,7 +558,6 @@ 77.238.189.142 permit 77.238.189.146/31 permit 77.238.189.148/30 permit -81.7.169.128/25 permit 81.223.46.0/27 permit 82.165.159.2 permit 82.165.159.3 permit @@ -1257,6 +1247,7 @@ 106.10.244.0/24 permit 106.39.212.64/29 permit 106.50.16.0/28 permit +107.20.18.111 permit 107.20.210.250 permit 108.174.0.0/24 permit 108.174.0.215 permit @@ -1292,8 +1283,6 @@ 117.120.16.0/21 permit 119.42.242.52/31 permit 119.42.242.156 permit -121.244.91.48 permit -122.15.156.182 permit 123.126.78.64/29 permit 124.108.96.24/31 permit 124.108.96.28/31 permit @@ -1349,18 +1338,7 @@ 134.170.141.64/26 permit 134.170.143.0/24 permit 134.170.174.0/24 permit -135.84.80.0/24 permit -135.84.81.0/24 permit -135.84.82.0/24 permit -135.84.83.0/24 permit 135.84.216.0/22 permit -136.143.160.0/24 permit -136.143.161.0/24 permit -136.143.178.49 permit -136.143.182.0/23 permit -136.143.184.0/24 permit -136.143.188.0/24 permit -136.143.190.0/23 permit 136.147.128.0/20 permit 136.147.135.0/24 permit 136.147.176.0/20 permit @@ -1368,7 +1346,6 @@ 136.147.182.0/24 permit 136.147.224.0/20 permit 136.179.50.206 permit -138.91.172.26 permit 139.60.152.0/22 permit 139.138.35.44 permit 139.138.46.121 permit @@ -1419,6 +1396,7 @@ 150.230.98.160 permit 152.67.105.195 permit 152.69.200.236 permit +152.70.155.126 permit 155.248.208.51 permit 157.55.0.192/26 permit 157.55.1.128/26 permit @@ -1475,7 +1453,6 @@ 163.114.134.16 permit 163.114.135.16 permit 164.177.132.168/30 permit -165.173.128.0/24 permit 166.78.68.0/22 permit 166.78.68.221 permit 166.78.69.169 permit @@ -1484,6 +1461,7 @@ 167.89.0.0/17 permit 167.89.46.159 permit 167.89.54.103 permit +167.89.60.95 permit 167.89.64.9 permit 167.89.65.0 permit 167.89.65.53 permit @@ -1502,11 +1480,6 @@ 168.245.12.252 permit 168.245.46.9 permit 168.245.127.231 permit -169.148.129.0/24 permit -169.148.131.0/24 permit -169.148.142.10 permit -169.148.144.0/25 permit -169.148.144.10 permit 170.10.68.0/22 permit 170.10.128.0/24 permit 170.10.129.0/24 permit @@ -1661,15 +1634,7 @@ 199.16.156.0/22 permit 199.33.145.1 permit 199.33.145.32 permit -199.34.22.36 permit 199.59.148.0/22 permit -199.67.80.2 permit -199.67.80.20 permit -199.67.82.2 permit -199.67.82.20 permit -199.67.84.0/24 permit -199.67.86.0/24 permit -199.67.88.0/24 permit 199.101.161.130 permit 199.101.162.0/25 permit 199.122.120.0/21 permit @@ -1726,8 +1691,6 @@ 204.92.114.187 permit 204.92.114.203 permit 204.92.114.204/31 permit -204.141.32.0/23 permit -204.141.42.0/23 permit 204.220.160.0/20 permit 204.232.168.0/24 permit 205.139.110.0/24 permit @@ -1979,8 +1942,6 @@ 2603:1030:20e:3::23c permit 2603:1030:b:3::152 permit 2603:1030:c02:8::14 permit -2607:13c0:0001:0000:0000:0000:0000:7000/116 permit -2607:13c0:0002:0000:0000:0000:0000:1000/116 permit 2607:f8b0:4000::/36 permit 2620:109:c003:104::/64 permit 2620:109:c003:104::215 permit From 82fde23cc1e42136444ea45e99dc15fea35afa28 Mon Sep 17 00:00:00 2001 From: Marcel Schuster Date: Thu, 1 Aug 2024 19:14:29 +0200 Subject: [PATCH 092/138] Bump watchdog to v2.03 --- docker-compose.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 3efd6a42..1e444e0d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -460,7 +460,7 @@ services: - /lib/modules:/lib/modules:ro watchdog-mailcow: - image: mailcow/watchdog:2.02 + image: mailcow/watchdog:2.03 dns: - ${IPV4_NETWORK:-172.22.1}.254 tmpfs: @@ -477,7 +477,6 @@ services: - mysql-mailcow - acme-mailcow - redis-mailcow - environment: - IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64} - LOG_LINES=${LOG_LINES:-9999} From 3885b07a997719ed518ee8cbabf9dc4608f5aab3 Mon Sep 17 00:00:00 2001 From: milkmaker Date: Mon, 5 Aug 2024 19:36:55 +0200 Subject: [PATCH 093/138] [Web] Updated lang.nb-no.json (#5980) Co-authored-by: Christer Solstrand Johannessen --- data/web/lang/lang.nb-no.json | 143 ++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/data/web/lang/lang.nb-no.json b/data/web/lang/lang.nb-no.json index 830d5b42..a6a7a0ca 100644 --- a/data/web/lang/lang.nb-no.json +++ b/data/web/lang/lang.nb-no.json @@ -322,5 +322,148 @@ "invalid_nexthop": "\"Next hop\"-format er ugyldig", "img_dimensions_exceeded": "Bildet overskriver maksimal bildestørrelse", "img_size_exceeded": "Bildet overskrider maksimal filstørrelse" + }, + "debug": { + "logs": "Logger", + "update_available": "En oppdatering er tilgjengelig", + "service": "Tjeneste", + "show_ip": "Vis offentlig IP", + "solr_dead": "Solr starter, er deaktivert eller døde", + "memory": "Minne", + "online_users": "Tilkoblede brukere", + "restart_container": "Omstart", + "size": "Størrelse", + "solr_status": "Solr-status", + "started_at": "Startet ved", + "started_on": "Startet den", + "static_logs": "Statiske logger", + "success": "Suksess", + "system_containers": "System og kontainere", + "timezone": "Tidssone", + "uptime": "Oppetid", + "no_update_available": "Systemet kjører siste versjon", + "update_failed": "Kunne ikke se etter oppdateringer", + "username": "Brukernavn", + "wip": "Foreløpig under utvikling" + }, + "diagnostics": { + "dns_records_24hours": "Vennligst vær oppmerksom på at endringer gjort i DNS kan ta opp til 24 timer før riktig status vises på denne siden. Den er ment som en måte for deg å enkelt se hvordan du kan sette opp DNS-oppføringene dine og se at alle oppføringer er korrekt lagret i DNS.", + "cname_from_a": "Verdi hentet fra A/AAAA-oppføring. Dette er støttet så lenge oppføringen peker til riktig ressurs.", + "dns_records_docs": "Vennligst også se dokumentasjonen.", + "dns_records": "DNS-oppføringer", + "dns_records_data": "Korrekte data", + "dns_records_name": "Navn", + "dns_records_status": "Nåværende status", + "dns_records_type": "Type", + "optional": "Denne oppføringen er valgfri." + }, + "edit": { + "bcc_dest_format": "BCC-destinasjon må være en enkelt, gyldig epostadresse.
Hvis du trenger å sende en kopi til flere adresser, opprett et alias og bruk det her.", + "pushover_info": "Innstillinger for pushvarslinger vil gjelde alle rene (ikke-spam) eposter levert til %s, inkludert aliaser (delte, ikke-delte, taggede).", + "relay_transport_info": "
Info
Du kan definere transportmappinger for et spesifikt mål for dette domenet. Hvis dette ikke er definert, blir det gjort et MX-oppslag.", + "delete2duplicates": "Slett duplikater på målvert", + "description": "Beskrivelse", + "disable_login": "Ikke tillat innlogging (innkommende epost blir likevel mottatt)", + "domain_admin": "Endre domeneadministrator", + "max_mailboxes": "Maks antall mailbokser", + "quota_warning_bcc_info": "Advarsler blir sendt som separate kopier til de følgende mottakerne. Emnet vil få lagt til det korresponderende brukernavnet i parantes, for eksempel: Kvotevarsel (user@example.com).", + "domain_footer_skip_replies": "Ignorer bunntekst ved svar på epost", + "extended_sender_acl": "Eksterne avsenderadresser", + "extended_sender_acl_info": "En DKIM-domenenøkkel bør importeres, hvis tilgjengelig.
\n Husk å legge denne serveren til den korresponderende SPF TXT-oppføringen.
\n Når et domene eller aliasdomene legges til på denne serveren, og det overlapper med en ekstern adresse, blir den eksterne adressen fjernet.
\n Bruk @domain.tld for å tillate sending som *@domain.tld.", + "password_repeat": "Bekreft passord (gjenta)", + "pushover_title": "Varslingstittel", + "pushover_vars": "Når et avsenderfilter ikke er definert, vil alle epostere bli vurdert.
Regex-filtre såvel så eksakte avsendersjekker kan bli individuelt definert og vil bli vurdert sekvensielt. De er ikke avhengige av hverandre.
Tilgjengelige variabler for tekst og tittel (vennligst observer policyer for databeskyttelse)", + "admin": "Endre administrator", + "domain_footer_info": "Bunntekst for hele domenet leggese til alle utgående eposter assosiert med en adresse innenfor dette domenet.
De følgende variablene kan brukes for bunnteksten:", + "domain_footer_info_vars": { + "custom": "{= foo =} - Hvis mailboksen har en spesialattributt \"foo\" med verdi \"bar\", vil den vise \"bar\"", + "auth_user": "{= auth_user =} - Autentisert brukernavn spesifisert av en MTA", + "from_user": "{= from_user =} - Fra brukerdelen av konvolutten, f.eks. for \"moo@mailcow.tld\" vil den returnere \"moo\"", + "from_name": "{= from_name =} - Fra-navn fra konvolutten, f.eks. for \"Mailcow <moo@mailcow.tld>\" vil den vise \"Mailcow\"", + "from_addr": "{= from_addr =} - Fra adressedelen av konvolutten", + "from_domain": "{= from_domain =} - Fra domene-delen av konvolutten" + }, + "mailbox_relayhost_info": "Aktiveres kun for mailboksen og direkte aliaser, overstyrer domene-videresendingsvert.", + "mbox_rl_info": "Denne begrensningen gjelder for SASL-innloggingsnavnet, dersom det er likt noen \"from\"-adresser benyttet av den innloggede brukeren. En mailboks-begrensning overstyrer en domene-begrensning.", + "allow_from_smtp_info": "La stå tom for å tillate alle avsendere.
IPv4/IPv6-adresser og -nettverk.", + "domain": "Endre domene", + "encryption": "Kryptering", + "exclude": "Ekskluder objekter (regex)", + "footer_exclude": "Ekskluder fra bunntekst", + "gal_info": "GAL inneholder alle objeker i et domene og kan ikke redigeres av noen brukere. Ledig/opptatt-informasjon i SOGo mangler dersom den deaktiveres! Start SOGo på nytt for å aktivere endringene.", + "grant_types": "Grant-typer", + "hostname": "Vertsnavn", + "inactive": "Inaktiv", + "kind": "Type", + "last_modified": "Sist endret", + "lookup_mx": "Målet er et regex-uttrykk for å matche mot MX_navnet (*\\.google\\.com for å route all epost som skal til en MX-server som slutter på google.com, via dette målet)", + "mailbox": "Endre mailboks", + "mailbox_quota_def": "Standardkvote for mailboks", + "max_quota": "Maks kvote pr. mailboks (MiB)", + "maxage": "Maksimal alder for meldinger, i dager, som vil hentes fra ekstern
(0 = ignorer alder)", + "maxbytespersecond": "Maks bytes pr. sekund
(0 = ubegrenset)", + "pushover_sender_array": "Bare vurder de følgende avsenderadressene (komma-separert)", + "pushover_sender_regex": "Vurder følgende avsender-regex", + "pushover_text": "Varslingstekst", + "pushover_sound": "Lyd", + "pushover_verify": "Bekreft identifikasjon", + "quota_mb": "Kvote (MiB)", + "quota_warning_bcc": "Kvotevarsling BCC", + "ratelimit": "Mengdebegrensning", + "domain_footer": "Bunntekst for hele domenet", + "private_comment": "Privat kommentar", + "public_comment": "Offentlig kommentar", + "client_id": "Klient-ID", + "full_name": "Fullt navn", + "gal": "Global adresseliste", + "max_aliases": "Maks. antall aliaser", + "mins_interval": "Intervall (min)", + "multiple_bookings": "Flere bookinger", + "none_inherit": "Ingen / arve", + "acl": "ACL (rettighet)", + "active": "Aktiv", + "advanced_settings": "Avanserte innstillinger", + "alias": "Endre alias", + "allow_from_smtp": "Tillat kun disse IPene å bruke SMTP", + "allowed_protocols": "Tillatte protokoller", + "app_name": "Appnavn", + "app_passwd": "App-passord", + "app_passwd_protocols": "Tillatte protokoller for app-passord", + "automap": "Prøv å automatisk mappe opp mapper (\"Sent items\", \"Sent\" => \"Sendt\" etc.)", + "backup_mx_options": "Videresendingsalternativer", + "client_secret": "Klient-hemmelighet", + "comment_info": "En privat kommentar er ikke synlig for brukeren, mens en offentlig kommentar vises som et tooltip når man holder muspekeren over det", + "created_on": "Opprettet den", + "custom_attributes": "Valgfrie attributter", + "delete1": "Slett fra kilde når fullført", + "delete2": "Slett meldinger på målvert som ikke finnes på kildeverten", + "delete_ays": "Vennligst bekreft slettingen.", + "domain_footer_html": "HTML-bunntekst", + "domain_footer_plain": "PLAIN-bunntekst", + "domain_quota": "Domenekvote", + "domains": "Domener", + "dont_check_sender_acl": "Deaktivere sendersjekk for domene %s (+ aliasdomener)", + "edit_alias_domain": "Endre aliasdomene", + "force_pw_update": "Tving endring av passord ved neste innlogging", + "force_pw_update_info": "Denne brukeren vil bare kunne logge inn på %s. App-passord kan fremdeles brukes.", + "generate": "generer", + "nexthop": "Neste hopp", + "password": "Passord", + "previous": "Forrige side", + "pushover": "Pushover", + "pushover_evaluate_x_prio": "Eskaler mail med høy prioritet [X-Priority: 1]", + "pushover_only_x_prio": "Bare vurder epost med høy prioritet [X-Priority: 1]", + "redirect_uri": "Omdirigerings-/tilbakekallings-URL", + "relay_all": "Videresend alle mottakere", + "relay_all_info": "↪ Hvis du velger å ikke videresende alle mottakkere, så må du legge til en (\"blind\") mailboks for hver eneste mottaker det skal videresendes for.", + "relay_domain": "Videresend dette domenet", + "relay_unknown_only": "Videresend kun ikke-eksisterende mailbokser. Eksisterende mailbokser vil bli levert lokalt.", + "relayhost": "Avsender-avhengige transportmetoder", + "remove": "Fjern", + "resource": "Ressurs", + "save": "Lagre endringer", + "scope": "Omfang", + "sender_acl": "Tillat å sende som", + "sender_acl_disabled": "Avsender-sjekk er deaktivert" } } From c9187261430672f41fdb7b432444e270454278ff Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Tue, 6 Aug 2024 12:04:04 +0200 Subject: [PATCH 094/138] dovecot: fix precompiling of sieve scripts --- data/Dockerfiles/dovecot/docker-entrypoint.sh | 8 -------- docker-compose.yml | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/data/Dockerfiles/dovecot/docker-entrypoint.sh b/data/Dockerfiles/dovecot/docker-entrypoint.sh index b53c06be..bd1a44f3 100755 --- a/data/Dockerfiles/dovecot/docker-entrypoint.sh +++ b/data/Dockerfiles/dovecot/docker-entrypoint.sh @@ -407,14 +407,6 @@ sievec /var/vmail/sieve/global_sieve_after.sieve sievec /usr/lib/dovecot/sieve/report-spam.sieve sievec /usr/lib/dovecot/sieve/report-ham.sieve -for file in /var/vmail/*/*/sieve/*.sieve ; do - if [[ "$file" == "/var/vmail/*/*/sieve/*.sieve" ]]; then - continue - fi - sievec "$file" "$(dirname "$file")/../.dovecot.svbin" - chown vmail:vmail "$(dirname "$file")/../.dovecot.svbin" -done - # Fix permissions chown root:root /etc/dovecot/sql/*.conf chown root:dovecot /etc/dovecot/sql/dovecot-dict-sql-sieve* /etc/dovecot/sql/dovecot-dict-sql-quota* /etc/dovecot/lua/passwd-verify.lua diff --git a/docker-compose.yml b/docker-compose.yml index ece85026..f673f1a0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -221,7 +221,7 @@ services: - sogo dovecot-mailcow: - image: mailcow/dovecot:1.30 + image: mailcow/dovecot:2.0 depends_on: - mysql-mailcow - netfilter-mailcow From 6ee0303b0f5b3953f66a21195eec1d08bdae1d98 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Tue, 6 Aug 2024 15:33:40 +0200 Subject: [PATCH 095/138] ui: added enotify and mime as valid options for ui --- data/web/inc/lib/sieve/extensions/enotify.xml | 33 +++++++++++ data/web/inc/lib/sieve/extensions/mime.xml | 58 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 data/web/inc/lib/sieve/extensions/enotify.xml create mode 100644 data/web/inc/lib/sieve/extensions/mime.xml diff --git a/data/web/inc/lib/sieve/extensions/enotify.xml b/data/web/inc/lib/sieve/extensions/enotify.xml new file mode 100644 index 00000000..b4686a33 --- /dev/null +++ b/data/web/inc/lib/sieve/extensions/enotify.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data/web/inc/lib/sieve/extensions/mime.xml b/data/web/inc/lib/sieve/extensions/mime.xml new file mode 100644 index 00000000..d7e200f0 --- /dev/null +++ b/data/web/inc/lib/sieve/extensions/mime.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From b0339372b5482781fffff6c39a286c01e5a2c65d Mon Sep 17 00:00:00 2001 From: Hassan A Hashim Date: Tue, 6 Aug 2024 17:12:54 +0300 Subject: [PATCH 096/138] Check `mailcow.conf` exists before source it --- update.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/update.sh b/update.sh index 0c8f85fe..ddfd06de 100755 --- a/update.sh +++ b/update.sh @@ -404,12 +404,13 @@ while (($#)); do shift done +[[ ! -f mailcow.conf ]] && { echo "mailcow.conf is missing! Is mailcow installed?"; exit 1;} + chmod 600 mailcow.conf source mailcow.conf detect_docker_compose_command -[[ ! -f mailcow.conf ]] && { echo "mailcow.conf is missing! Is mailcow installed?"; exit 1;} DOTS=${MAILCOW_HOSTNAME//[^.]}; if [ ${#DOTS} -lt 1 ]; then echo -e "\e[31mMAILCOW_HOSTNAME (${MAILCOW_HOSTNAME}) is not a FQDN!\e[0m" From 926af87cfb19cb3fdad8da992dccc2d506400079 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Tue, 6 Aug 2024 16:20:28 +0200 Subject: [PATCH 097/138] scripts: adding docker version check to align to docs (24.X) --- generate_config.sh | 10 ++++++++++ update.sh | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/generate_config.sh b/generate_config.sh index 4b99092b..cc5ba1ce 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -25,6 +25,16 @@ for bin in openssl curl docker git awk sha1sum grep cut; do if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi done +# Check Docker Version (need at least 24.X) +docker_version=$(docker -v | grep -oP '\d+\.\d+\.\d+' | cut -d '.' -f 1) + +if [[ $docker_version -lt 24 ]]; then + echo -e "\e[31mCannot find Docker with a Version higher or equals 24.0.0\e[0m" + echo -e "\e[33mmailcow needs a newer Docker version to work properly...\e[0m" + echo -e "\e[31mPlease update your Docker installation... exiting\e[0m" + exit 1 +fi + if docker compose > /dev/null 2>&1; then if docker compose version --short | grep -e "^2." -e "^v2." > /dev/null 2>&1; then COMPOSE_VERSION=native diff --git a/update.sh b/update.sh index 0c8f85fe..b07ebb0a 100755 --- a/update.sh +++ b/update.sh @@ -328,6 +328,16 @@ for bin in curl docker git awk sha1sum grep cut; do fi done +# Check Docker Version (need at least 24.X) +docker_version=$(docker -v | grep -oP '\d+\.\d+\.\d+' | cut -d '.' -f 1) + +if [[ $docker_version -lt 24 ]]; then + echo -e "\e[31mCannot find Docker with a Version higher or equals 24.0.0\e[0m" + echo -e "\e[33mmailcow needs a newer Docker version to work properly... continuing on your own risk!\e[0m" + echo -e "\e[31mPlease update your Docker installation... exiting\e[0m" + sleep 10 +fi + export LC_ALL=C DATE=$(date +%Y-%m-%d_%H_%M_%S) BRANCH=$(cd ${SCRIPT_DIR}; git rev-parse --abbrev-ref HEAD) From a001a0584f12c19efd6054b417284a5488f8eb74 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Tue, 6 Aug 2024 16:21:28 +0200 Subject: [PATCH 098/138] update.sh: fix text for min. docker ver --- update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update.sh b/update.sh index b07ebb0a..fe4ebf89 100755 --- a/update.sh +++ b/update.sh @@ -334,7 +334,7 @@ docker_version=$(docker -v | grep -oP '\d+\.\d+\.\d+' | cut -d '.' -f 1) if [[ $docker_version -lt 24 ]]; then echo -e "\e[31mCannot find Docker with a Version higher or equals 24.0.0\e[0m" echo -e "\e[33mmailcow needs a newer Docker version to work properly... continuing on your own risk!\e[0m" - echo -e "\e[31mPlease update your Docker installation... exiting\e[0m" + echo -e "\e[31mPlease update your Docker installation... sleeping 10s\e[0m" sleep 10 fi From cc0dc2eae090fec01320d619b0008e82bebca315 Mon Sep 17 00:00:00 2001 From: Hassan A Hashim Date: Tue, 6 Aug 2024 17:51:46 +0300 Subject: [PATCH 099/138] Add color-coded error message for missing `mailcow.conf` --- update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update.sh b/update.sh index ddfd06de..6db943a0 100755 --- a/update.sh +++ b/update.sh @@ -404,7 +404,7 @@ while (($#)); do shift done -[[ ! -f mailcow.conf ]] && { echo "mailcow.conf is missing! Is mailcow installed?"; exit 1;} +[[ ! -f mailcow.conf ]] && { echo -e "\e[31mmailcow.conf is missing! Is mailcow installed?\e[0m"; exit 1;} chmod 600 mailcow.conf source mailcow.conf From e994cf4d0575aec5690663c2713f974f415db862 Mon Sep 17 00:00:00 2001 From: Hassan A Hashim Date: Tue, 6 Aug 2024 20:38:18 +0300 Subject: [PATCH 100/138] Fix typo in `update.sh`: Proceeding --- update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update.sh b/update.sh index fe4ebf89..5e110810 100755 --- a/update.sh +++ b/update.sh @@ -434,7 +434,7 @@ elif [ ${#DOTS} -eq 1 ]; then echo "Find more information about why this message exists here: https://github.com/mailcow/mailcow-dockerized/issues/1572" read -r -p "Do you want to proceed anyway? [y/N] " response if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then - echo "OK. Procceding." + echo "OK. Proceeding." else echo "OK. Exiting." exit 1 From b3e0a6622297bc1c7d25d5d70ab84c7eab0943c7 Mon Sep 17 00:00:00 2001 From: Hassan A Hashim Date: Tue, 6 Aug 2024 21:03:17 +0300 Subject: [PATCH 101/138] Fix typo: receiving updates from `an` unsupported branch --- update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update.sh b/update.sh index 5e110810..af18e7c6 100755 --- a/update.sh +++ b/update.sh @@ -817,7 +817,7 @@ if ! [ $NEW_BRANCH ]; then echo -e "\e[33mTo change that run the update.sh Script one time with the --stable parameter to switch to stable builds.\e[0m" else - echo -e "\e[33mYou are receiving updates from a unsupported branch.\e[0m" + echo -e "\e[33mYou are receiving updates from an unsupported branch.\e[0m" sleep 1 echo -e "\e[33mThe mailcow stack might still work but it is recommended to switch to the master branch (stable builds).\e[0m" echo -e "\e[33mTo change that run the update.sh Script one time with the --stable parameter to switch to stable builds.\e[0m" From 292306b191f952d2b853fb02458e6fc9bf066c2b Mon Sep 17 00:00:00 2001 From: Hassan A Hashim Date: Tue, 6 Aug 2024 21:12:20 +0300 Subject: [PATCH 102/138] Fix typos and English grammar in `update.sh` German is different in using upper-case than English lol --- update.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/update.sh b/update.sh index af18e7c6..148dfe67 100755 --- a/update.sh +++ b/update.sh @@ -828,14 +828,14 @@ elif [ $FORCE ]; then echo -e "\e[31mPlease rerun the update.sh Script without the --force/-f parameter.\e[0m" sleep 1 elif [ $NEW_BRANCH == "master" ] && [ $CURRENT_BRANCH != "master" ]; then - echo -e "\e[33mYou are about to switch your mailcow Updates to the stable (master) branch.\e[0m" + echo -e "\e[33mYou are about to switch your mailcow updates to the stable (master) branch.\e[0m" sleep 1 - echo -e "\e[33mBefore you do: Please take a backup of all components to ensure that no Data is lost...\e[0m" + echo -e "\e[33mBefore you do: Please take a backup of all components to ensure that no data is lost...\e[0m" sleep 1 - echo -e "\e[31mWARNING: Please see on GitHub or ask in the communitys if a switch to master is stable or not. - In some rear cases a Update back to master can destroy your mailcow configuration in case of Database Upgrades etc. - Normally a upgrade back to master should be safe during each full release. - Check GitHub for Database Changes and Update only if there similar to the full release!\e[0m" + echo -e "\e[31mWARNING: Please see on GitHub or ask in the community if a switch to master is stable or not. + In some rear cases an update back to master can destroy your mailcow configuration such as database upgrade, etc. + Normally an upgrade back to master should be safe during each full release. + Check GitHub for Database changes and update only if there similar to the full release!\e[0m" read -r -p "Are you sure you that want to continue upgrading to the stable (master) branch? [y/N] " response if [[ ! "${response}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then echo "OK. If you prepared yourself for that please run the update.sh Script with the --stable parameter again to trigger this process here." From 3bf90c1f73412073eca44219eb55a1c54d793406 Mon Sep 17 00:00:00 2001 From: Hassan A Hashim Date: Tue, 6 Aug 2024 21:22:30 +0300 Subject: [PATCH 103/138] Fix typo for word `Potential` in `update.sh` file. --- update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update.sh b/update.sh index 148dfe67..9191055d 100755 --- a/update.sh +++ b/update.sh @@ -982,7 +982,7 @@ if [ ! $DEV ]; then echo -e "\e[31m\nOh no, what happened?\n=> You most likely added files to your local mailcow instance that were now added to the official mailcow repository. Please move them to another location before updating mailcow.\e[0m" exit 1 elif [[ ${MERGE_RETURN} == 1 ]]; then - echo -e "\e[93mPotenial conflict, trying to fix...\e[0m" + echo -e "\e[93mPotential conflict, trying to fix...\e[0m" git status --porcelain | grep -E "UD|DU" | awk '{print $2}' | xargs rm -v git add -A git commit -m "After update on ${DATE}" > /dev/null From edd85dea8dc194092aa4ae1b60ec943213ea0928 Mon Sep 17 00:00:00 2001 From: Hassan A Hashim Date: Tue, 6 Aug 2024 22:44:59 +0300 Subject: [PATCH 104/138] Fix `LABEL` in Dockerfile, should be key=value Refering to the [Official Docker Docs](`https://docs.docker.com/reference/dockerfile/#label`), clearly said the format of LABEL is `LABEL = = = ...`. --- data/Dockerfiles/acme/Dockerfile | 2 +- data/Dockerfiles/clamd/Dockerfile | 2 +- data/Dockerfiles/dockerapi/Dockerfile | 2 +- data/Dockerfiles/dovecot/Dockerfile | 3 ++- data/Dockerfiles/netfilter/Dockerfile | 3 ++- data/Dockerfiles/olefy/Dockerfile | 3 ++- data/Dockerfiles/phpfpm/Dockerfile | 3 ++- data/Dockerfiles/postfix/Dockerfile | 3 ++- data/Dockerfiles/rspamd/Dockerfile | 3 ++- data/Dockerfiles/sogo/Dockerfile | 3 ++- data/Dockerfiles/unbound/Dockerfile | 2 +- data/Dockerfiles/watchdog/Dockerfile | 3 ++- 12 files changed, 20 insertions(+), 12 deletions(-) diff --git a/data/Dockerfiles/acme/Dockerfile b/data/Dockerfiles/acme/Dockerfile index 8688e440..8aa16ad5 100644 --- a/data/Dockerfiles/acme/Dockerfile +++ b/data/Dockerfiles/acme/Dockerfile @@ -1,6 +1,6 @@ FROM alpine:3.20 -LABEL maintainer "The Infrastructure Company GmbH " +LABEL maintainer = "The Infrastructure Company GmbH " RUN apk upgrade --no-cache \ diff --git a/data/Dockerfiles/clamd/Dockerfile b/data/Dockerfiles/clamd/Dockerfile index ab1e2550..1850d4be 100644 --- a/data/Dockerfiles/clamd/Dockerfile +++ b/data/Dockerfiles/clamd/Dockerfile @@ -1,6 +1,6 @@ FROM alpine:3.20 -LABEL maintainer "The Infrastructure Company GmbH " +LABEL maintainer = "The Infrastructure Company GmbH " RUN apk upgrade --no-cache \ && apk add --update --no-cache \ diff --git a/data/Dockerfiles/dockerapi/Dockerfile b/data/Dockerfiles/dockerapi/Dockerfile index 511c4623..92c19dcc 100644 --- a/data/Dockerfiles/dockerapi/Dockerfile +++ b/data/Dockerfiles/dockerapi/Dockerfile @@ -1,6 +1,6 @@ FROM alpine:3.20 -LABEL maintainer "The Infrastructure Company GmbH " +LABEL maintainer = "The Infrastructure Company GmbH " ARG PIP_BREAK_SYSTEM_PACKAGES=1 WORKDIR /app diff --git a/data/Dockerfiles/dovecot/Dockerfile b/data/Dockerfiles/dovecot/Dockerfile index 65028b17..a832bff6 100644 --- a/data/Dockerfiles/dovecot/Dockerfile +++ b/data/Dockerfiles/dovecot/Dockerfile @@ -1,5 +1,6 @@ FROM alpine:3.20 -LABEL maintainer "The Infrastructure Company GmbH " + +LABEL maintainer = "The Infrastructure Company GmbH " # renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^(?.*)$ ARG GOSU_VERSION=1.16 diff --git a/data/Dockerfiles/netfilter/Dockerfile b/data/Dockerfiles/netfilter/Dockerfile index 4f65f8e0..86f9e3f6 100644 --- a/data/Dockerfiles/netfilter/Dockerfile +++ b/data/Dockerfiles/netfilter/Dockerfile @@ -1,5 +1,6 @@ FROM alpine:3.20 -LABEL maintainer "The Infrastructure Company GmbH " + +LABEL maintainer = "The Infrastructure Company GmbH " WORKDIR /app diff --git a/data/Dockerfiles/olefy/Dockerfile b/data/Dockerfiles/olefy/Dockerfile index e71ea9ff..3b272913 100644 --- a/data/Dockerfiles/olefy/Dockerfile +++ b/data/Dockerfiles/olefy/Dockerfile @@ -1,5 +1,6 @@ FROM alpine:3.20 -LABEL maintainer "The Infrastructure Company GmbH " + +LABEL maintainer = "The Infrastructure Company GmbH " ARG PIP_BREAK_SYSTEM_PACKAGES=1 WORKDIR /app diff --git a/data/Dockerfiles/phpfpm/Dockerfile b/data/Dockerfiles/phpfpm/Dockerfile index 22036b9b..0ac722b2 100644 --- a/data/Dockerfiles/phpfpm/Dockerfile +++ b/data/Dockerfiles/phpfpm/Dockerfile @@ -1,5 +1,6 @@ FROM php:8.2-fpm-alpine3.18 -LABEL maintainer "The Infrastructure Company GmbH " + +LABEL maintainer = "The Infrastructure Company GmbH " # renovate: datasource=github-tags depName=krakjoe/apcu versioning=semver-coerced extractVersion=^v(?.*)$ ARG APCU_PECL_VERSION=5.1.23 diff --git a/data/Dockerfiles/postfix/Dockerfile b/data/Dockerfiles/postfix/Dockerfile index a45ce12b..0f1911c6 100644 --- a/data/Dockerfiles/postfix/Dockerfile +++ b/data/Dockerfiles/postfix/Dockerfile @@ -1,5 +1,6 @@ FROM debian:bookworm-slim -LABEL maintainer "The Infrastructure Company GmbH " + +LABEL maintainer = "The Infrastructure Company GmbH " ARG DEBIAN_FRONTEND=noninteractive ENV LC_ALL C diff --git a/data/Dockerfiles/rspamd/Dockerfile b/data/Dockerfiles/rspamd/Dockerfile index 07f0bc36..76956244 100644 --- a/data/Dockerfiles/rspamd/Dockerfile +++ b/data/Dockerfiles/rspamd/Dockerfile @@ -1,5 +1,6 @@ FROM debian:bullseye-slim -LABEL maintainer "The Infrastructure Company GmbH " + +LABEL maintainer = "The Infrastructure Company GmbH " ARG DEBIAN_FRONTEND=noninteractive ARG RSPAMD_VER=rspamd_3.7.5-2~8c86c1676 diff --git a/data/Dockerfiles/sogo/Dockerfile b/data/Dockerfiles/sogo/Dockerfile index 760c9501..6366c12f 100644 --- a/data/Dockerfiles/sogo/Dockerfile +++ b/data/Dockerfiles/sogo/Dockerfile @@ -1,5 +1,6 @@ FROM debian:bullseye-slim -LABEL maintainer "The Infrastructure Company GmbH " + +LABEL maintainer = "The Infrastructure Company GmbH " ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_VERSION=bullseye diff --git a/data/Dockerfiles/unbound/Dockerfile b/data/Dockerfiles/unbound/Dockerfile index 0ad5a05f..958d24e5 100644 --- a/data/Dockerfiles/unbound/Dockerfile +++ b/data/Dockerfiles/unbound/Dockerfile @@ -1,6 +1,6 @@ FROM alpine:3.20 -LABEL maintainer "The Infrastructure Company GmbH " +LABEL maintainer = "The Infrastructure Company GmbH " RUN apk add --update --no-cache \ curl \ diff --git a/data/Dockerfiles/watchdog/Dockerfile b/data/Dockerfiles/watchdog/Dockerfile index a844d73b..0f3e7dfb 100644 --- a/data/Dockerfiles/watchdog/Dockerfile +++ b/data/Dockerfiles/watchdog/Dockerfile @@ -1,5 +1,6 @@ FROM alpine:3.20 -LABEL maintainer "The Infrastructure Company GmbH " + +LABEL maintainer = "The Infrastructure Company GmbH " # Installation RUN apk add --update \ From 8fe1cc49618b4525c8ed163092a2a3271ccbf9e7 Mon Sep 17 00:00:00 2001 From: Kasim Date: Mon, 22 Jul 2024 23:55:31 +0100 Subject: [PATCH 105/138] change nginx address #5962 --- data/Dockerfiles/acme/acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/Dockerfiles/acme/acme.sh b/data/Dockerfiles/acme/acme.sh index 9d04d10c..f6821af4 100755 --- a/data/Dockerfiles/acme/acme.sh +++ b/data/Dockerfiles/acme/acme.sh @@ -123,7 +123,7 @@ done log_f "Database OK" log_f "Waiting for Nginx..." -until $(curl --output /dev/null --silent --head --fail http://nginx:8081); do +until $(curl --output /dev/null --silent --head --fail http://nginx.mailcowdockerized_mailcow-network:8081); do sleep 2 done log_f "Nginx OK" @@ -137,7 +137,7 @@ log_f "Resolver OK" # Waiting for domain table log_f "Waiting for domain table..." while [[ -z ${DOMAIN_TABLE} ]]; do - curl --silent http://nginx/ >/dev/null 2>&1 + curl --silent http://nginx.mailcowdockerized_mailcow-network/ >/dev/null 2>&1 DOMAIN_TABLE=$(mysql --socket=/var/run/mysqld/mysqld.sock -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "SHOW TABLES LIKE 'domain'" -Bs) [[ -z ${DOMAIN_TABLE} ]] && sleep 10 done From 0cdf7647c4669eb84942e9a978f13817a5c80ac1 Mon Sep 17 00:00:00 2001 From: Kasim Date: Wed, 24 Jul 2024 23:07:42 +0100 Subject: [PATCH 106/138] Include COMPOSE_PROJECT_NAME in Nginx url --- data/Dockerfiles/acme/acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/Dockerfiles/acme/acme.sh b/data/Dockerfiles/acme/acme.sh index f6821af4..9682684e 100755 --- a/data/Dockerfiles/acme/acme.sh +++ b/data/Dockerfiles/acme/acme.sh @@ -123,7 +123,7 @@ done log_f "Database OK" log_f "Waiting for Nginx..." -until $(curl --output /dev/null --silent --head --fail http://nginx.mailcowdockerized_mailcow-network:8081); do +until $(curl --output /dev/null --silent --head --fail http://nginx.${COMPOSE_PROJECT_NAME}_mailcow-network:8081); do sleep 2 done log_f "Nginx OK" @@ -137,7 +137,7 @@ log_f "Resolver OK" # Waiting for domain table log_f "Waiting for domain table..." while [[ -z ${DOMAIN_TABLE} ]]; do - curl --silent http://nginx.mailcowdockerized_mailcow-network/ >/dev/null 2>&1 + curl --silent http://nginx.${COMPOSE_PROJECT_NAME}_mailcow-network/ >/dev/null 2>&1 DOMAIN_TABLE=$(mysql --socket=/var/run/mysqld/mysqld.sock -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "SHOW TABLES LIKE 'domain'" -Bs) [[ -z ${DOMAIN_TABLE} ]] && sleep 10 done From b56291f62b07df92ebff1b119379c0007bfe9d47 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Wed, 7 Aug 2024 09:50:57 +0200 Subject: [PATCH 107/138] adapt scheme to affected curl containers (dirty way... but workaround) --- data/Dockerfiles/acme/reload-configurations.sh | 14 +++++++------- data/Dockerfiles/dovecot/rspamd-pipe-ham | 6 +++--- data/Dockerfiles/dovecot/rspamd-pipe-spam | 6 +++--- data/Dockerfiles/dovecot/sa-rules.sh | 4 ++-- data/Dockerfiles/phpfpm/docker-entrypoint.sh | 10 +++++----- data/Dockerfiles/watchdog/watchdog.sh | 14 +++++++------- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/data/Dockerfiles/acme/reload-configurations.sh b/data/Dockerfiles/acme/reload-configurations.sh index d5461a4d..8d194b68 100644 --- a/data/Dockerfiles/acme/reload-configurations.sh +++ b/data/Dockerfiles/acme/reload-configurations.sh @@ -2,32 +2,32 @@ # Reading container IDs # Wrapping as array to ensure trimmed content when calling $NGINX etc. -NGINX=($(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"nginx-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" | tr "\n" " ")) -DOVECOT=($(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"dovecot-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" | tr "\n" " ")) -POSTFIX=($(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"postfix-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" | tr "\n" " ")) +NGINX=($(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"nginx-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" | tr "\n" " ")) +DOVECOT=($(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"dovecot-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" | tr "\n" " ")) +POSTFIX=($(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"postfix-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" | tr "\n" " ")) reload_nginx(){ echo "Reloading Nginx..." - NGINX_RELOAD_RET=$(curl -X POST --insecure https://dockerapi/containers/${NGINX}/exec -d '{"cmd":"reload", "task":"nginx"}' --silent -H 'Content-type: application/json' | jq -r .type) + NGINX_RELOAD_RET=$(curl -X POST --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${NGINX}/exec -d '{"cmd":"reload", "task":"nginx"}' --silent -H 'Content-type: application/json' | jq -r .type) [[ ${NGINX_RELOAD_RET} != 'success' ]] && { echo "Could not reload Nginx, restarting container..."; restart_container ${NGINX} ; } } reload_dovecot(){ echo "Reloading Dovecot..." - DOVECOT_RELOAD_RET=$(curl -X POST --insecure https://dockerapi/containers/${DOVECOT}/exec -d '{"cmd":"reload", "task":"dovecot"}' --silent -H 'Content-type: application/json' | jq -r .type) + DOVECOT_RELOAD_RET=$(curl -X POST --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${DOVECOT}/exec -d '{"cmd":"reload", "task":"dovecot"}' --silent -H 'Content-type: application/json' | jq -r .type) [[ ${DOVECOT_RELOAD_RET} != 'success' ]] && { echo "Could not reload Dovecot, restarting container..."; restart_container ${DOVECOT} ; } } reload_postfix(){ echo "Reloading Postfix..." - POSTFIX_RELOAD_RET=$(curl -X POST --insecure https://dockerapi/containers/${POSTFIX}/exec -d '{"cmd":"reload", "task":"postfix"}' --silent -H 'Content-type: application/json' | jq -r .type) + POSTFIX_RELOAD_RET=$(curl -X POST --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${POSTFIX}/exec -d '{"cmd":"reload", "task":"postfix"}' --silent -H 'Content-type: application/json' | jq -r .type) [[ ${POSTFIX_RELOAD_RET} != 'success' ]] && { echo "Could not reload Postfix, restarting container..."; restart_container ${POSTFIX} ; } } restart_container(){ for container in $*; do echo "Restarting ${container}..." - C_REST_OUT=$(curl -X POST --insecure https://dockerapi/containers/${container}/restart --silent | jq -r '.msg') + C_REST_OUT=$(curl -X POST --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${container}/restart --silent | jq -r '.msg') echo "${C_REST_OUT}" done } diff --git a/data/Dockerfiles/dovecot/rspamd-pipe-ham b/data/Dockerfiles/dovecot/rspamd-pipe-ham index 732af858..b9a84f1b 100755 --- a/data/Dockerfiles/dovecot/rspamd-pipe-ham +++ b/data/Dockerfiles/dovecot/rspamd-pipe-ham @@ -3,8 +3,8 @@ FILE=/tmp/mail$$ cat > $FILE trap "/bin/rm -f $FILE" 0 1 2 3 13 15 -cat ${FILE} | /usr/bin/curl -H "Flag: 11" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/fuzzydel -cat ${FILE} | /usr/bin/curl -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/learnham -cat ${FILE} | /usr/bin/curl -H "Flag: 13" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/fuzzyadd +cat ${FILE} | /usr/bin/curl -H "Flag: 11" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/fuzzydel +cat ${FILE} | /usr/bin/curl -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/learnham +cat ${FILE} | /usr/bin/curl -H "Flag: 13" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/fuzzyadd exit 0 diff --git a/data/Dockerfiles/dovecot/rspamd-pipe-spam b/data/Dockerfiles/dovecot/rspamd-pipe-spam index a4b91a01..3f02c487 100755 --- a/data/Dockerfiles/dovecot/rspamd-pipe-spam +++ b/data/Dockerfiles/dovecot/rspamd-pipe-spam @@ -3,8 +3,8 @@ FILE=/tmp/mail$$ cat > $FILE trap "/bin/rm -f $FILE" 0 1 2 3 13 15 -cat ${FILE} | /usr/bin/curl -H "Flag: 13" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/fuzzydel -cat ${FILE} | /usr/bin/curl -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/learnspam -cat ${FILE} | /usr/bin/curl -H "Flag: 11" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/fuzzyadd +cat ${FILE} | /usr/bin/curl -H "Flag: 13" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/fuzzydel +cat ${FILE} | /usr/bin/curl -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/learnspam +cat ${FILE} | /usr/bin/curl -H "Flag: 11" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/fuzzyadd exit 0 diff --git a/data/Dockerfiles/dovecot/sa-rules.sh b/data/Dockerfiles/dovecot/sa-rules.sh index cbfeb5af..107ea717 100755 --- a/data/Dockerfiles/dovecot/sa-rules.sh +++ b/data/Dockerfiles/dovecot/sa-rules.sh @@ -21,11 +21,11 @@ sed -i -e 's/\([^\\]\)\$\([^\/]\)/\1\\$\2/g' /etc/rspamd/custom/sa-rules if [[ "$(cat /etc/rspamd/custom/sa-rules | md5sum | cut -d' ' -f1)" != "${HASH_SA_RULES}" ]]; then CONTAINER_NAME=rspamd-mailcow - CONTAINER_ID=$(curl --silent --insecure https://dockerapi/containers/json | \ + CONTAINER_ID=$(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | \ jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | \ jq -rc "select( .name | tostring | contains(\"${CONTAINER_NAME}\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id") if [[ ! -z ${CONTAINER_ID} ]]; then - curl --silent --insecure -XPOST --connect-timeout 15 --max-time 120 https://dockerapi/containers/${CONTAINER_ID}/restart + curl --silent --insecure -XPOST --connect-timeout 15 --max-time 120 https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${CONTAINER_ID}/restart fi fi diff --git a/data/Dockerfiles/phpfpm/docker-entrypoint.sh b/data/Dockerfiles/phpfpm/docker-entrypoint.sh index e6c26fd1..87b4e298 100755 --- a/data/Dockerfiles/phpfpm/docker-entrypoint.sh +++ b/data/Dockerfiles/phpfpm/docker-entrypoint.sh @@ -23,7 +23,7 @@ done # Check mysql_upgrade (master and slave) CONTAINER_ID= until [[ ! -z "${CONTAINER_ID}" ]] && [[ "${CONTAINER_ID}" =~ ^[[:alnum:]]*$ ]]; do - CONTAINER_ID=$(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" 2> /dev/null | jq -rc "select( .name | tostring | contains(\"mysql-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" 2> /dev/null) + CONTAINER_ID=$(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" 2> /dev/null | jq -rc "select( .name | tostring | contains(\"mysql-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" 2> /dev/null) echo "Could not get mysql-mailcow container id... trying again" sleep 2 done @@ -35,7 +35,7 @@ until [[ ${SQL_UPGRADE_STATUS} == 'success' ]]; do echo "Tried to upgrade MySQL and failed, giving up after ${SQL_LOOP_C} retries and starting container (oops, not good)" break fi - SQL_FULL_UPGRADE_RETURN=$(curl --silent --insecure -XPOST https://dockerapi/containers/${CONTAINER_ID}/exec -d '{"cmd":"system", "task":"mysql_upgrade"}' --silent -H 'Content-type: application/json') + SQL_FULL_UPGRADE_RETURN=$(curl --silent --insecure -XPOST https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${CONTAINER_ID}/exec -d '{"cmd":"system", "task":"mysql_upgrade"}' --silent -H 'Content-type: application/json') SQL_UPGRADE_STATUS=$(echo ${SQL_FULL_UPGRADE_RETURN} | jq -r .type) SQL_LOOP_C=$((SQL_LOOP_C+1)) echo "SQL upgrade iteration #${SQL_LOOP_C}" @@ -60,12 +60,12 @@ done # doing post-installation stuff, if SQL was upgraded (master and slave) if [ ${SQL_CHANGED} -eq 1 ]; then - POSTFIX=$(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" 2> /dev/null | jq -rc "select( .name | tostring | contains(\"postfix-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" 2> /dev/null) + POSTFIX=$(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" 2> /dev/null | jq -rc "select( .name | tostring | contains(\"postfix-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" 2> /dev/null) if [[ -z "${POSTFIX}" ]] || ! [[ "${POSTFIX}" =~ ^[[:alnum:]]*$ ]]; then echo "Could not determine Postfix container ID, skipping Postfix restart." else echo "Restarting Postfix" - curl -X POST --silent --insecure https://dockerapi/containers/${POSTFIX}/restart | jq -r '.msg' + curl -X POST --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${POSTFIX}/restart | jq -r '.msg' echo "Sleeping 5 seconds..." sleep 5 fi @@ -74,7 +74,7 @@ fi # Check mysql tz import (master and slave) TZ_CHECK=$(mysql --socket=/var/run/mysqld/mysqld.sock -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "SELECT CONVERT_TZ('2019-11-02 23:33:00','Europe/Berlin','UTC') AS time;" -BN 2> /dev/null) if [[ -z ${TZ_CHECK} ]] || [[ "${TZ_CHECK}" == "NULL" ]]; then - SQL_FULL_TZINFO_IMPORT_RETURN=$(curl --silent --insecure -XPOST https://dockerapi/containers/${CONTAINER_ID}/exec -d '{"cmd":"system", "task":"mysql_tzinfo_to_sql"}' --silent -H 'Content-type: application/json') + SQL_FULL_TZINFO_IMPORT_RETURN=$(curl --silent --insecure -XPOST https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${CONTAINER_ID}/exec -d '{"cmd":"system", "task":"mysql_tzinfo_to_sql"}' --silent -H 'Content-type: application/json') echo "MySQL mysql_tzinfo_to_sql - debug output:" echo ${SQL_FULL_TZINFO_IMPORT_RETURN} fi diff --git a/data/Dockerfiles/watchdog/watchdog.sh b/data/Dockerfiles/watchdog/watchdog.sh index cb342c13..d4de6d8d 100755 --- a/data/Dockerfiles/watchdog/watchdog.sh +++ b/data/Dockerfiles/watchdog/watchdog.sh @@ -191,12 +191,12 @@ get_container_ip() { else sleep 0.5 # get long container id for exact match - CONTAINER_ID=($(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring == \"${1}\") | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id")) + CONTAINER_ID=($(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring == \"${1}\") | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id")) # returned id can have multiple elements (if scaled), shuffle for random test CONTAINER_ID=($(printf "%s\n" "${CONTAINER_ID[@]}" | shuf)) if [[ ! -z ${CONTAINER_ID} ]]; then for matched_container in "${CONTAINER_ID[@]}"; do - CONTAINER_IPS=($(curl --silent --insecure https://dockerapi/containers/${matched_container}/json | jq -r '.NetworkSettings.Networks[].IPAddress')) + CONTAINER_IPS=($(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${matched_container}/json | jq -r '.NetworkSettings.Networks[].IPAddress')) for ip_match in "${CONTAINER_IPS[@]}"; do # grep will do nothing if one of these vars is empty [[ -z ${ip_match} ]] && continue @@ -716,7 +716,7 @@ rspamd_checks() { From: watchdog@localhost Empty -' | usr/bin/curl --max-time 10 -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/scan | jq -rc .default.required_score | sed 's/\..*//' ) +' | usr/bin/curl --max-time 10 -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/scan | jq -rc .default.required_score | sed 's/\..*//' ) if [[ ${SCORE} -ne 9999 ]]; then echo "Rspamd settings check failed, score returned: ${SCORE}" 2>> /tmp/rspamd-mailcow 1>&2 err_count=$(( ${err_count} + 1)) @@ -1095,12 +1095,12 @@ while true; do elif [[ ${com_pipe_answer} =~ .+-mailcow ]]; then kill -STOP ${BACKGROUND_TASKS[*]} sleep 10 - CONTAINER_ID=$(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"${com_pipe_answer}\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id") + CONTAINER_ID=$(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"${com_pipe_answer}\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id") if [[ ! -z ${CONTAINER_ID} ]]; then if [[ "${com_pipe_answer}" == "php-fpm-mailcow" ]]; then - HAS_INITDB=$(curl --silent --insecure -XPOST https://dockerapi/containers/${CONTAINER_ID}/top | jq '.msg.Processes[] | contains(["php -c /usr/local/etc/php -f /web/inc/init_db.inc.php"])' | grep true) + HAS_INITDB=$(curl --silent --insecure -XPOST https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${CONTAINER_ID}/top | jq '.msg.Processes[] | contains(["php -c /usr/local/etc/php -f /web/inc/init_db.inc.php"])' | grep true) fi - S_RUNNING=$(($(date +%s) - $(curl --silent --insecure https://dockerapi/containers/${CONTAINER_ID}/json | jq .State.StartedAt | xargs -n1 date +%s -d))) + S_RUNNING=$(($(date +%s) - $(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${CONTAINER_ID}/json | jq .State.StartedAt | xargs -n1 date +%s -d))) if [ ${S_RUNNING} -lt 360 ]; then log_msg "Container is running for less than 360 seconds, skipping action..." elif [[ ! -z ${HAS_INITDB} ]]; then @@ -1108,7 +1108,7 @@ while true; do sleep 60 else log_msg "Sending restart command to ${CONTAINER_ID}..." - curl --silent --insecure -XPOST https://dockerapi/containers/${CONTAINER_ID}/restart + curl --silent --insecure -XPOST https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${CONTAINER_ID}/restart notify_error "${com_pipe_answer}" log_msg "Wait for restarted container to settle and continue watching..." sleep 35 From a4c006828e7d167b41fd9856262ac5bbbd343c14 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Wed, 7 Aug 2024 09:51:47 +0200 Subject: [PATCH 108/138] compose: bump container tags --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index f673f1a0..b5875481 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -110,7 +110,7 @@ services: - rspamd php-fpm-mailcow: - image: mailcow/phpfpm:1.87 + image: mailcow/phpfpm:1.88 command: "php-fpm -d date.timezone=${TZ} -d expose_php=0" depends_on: - redis-mailcow @@ -405,7 +405,7 @@ services: condition: service_started unbound-mailcow: condition: service_healthy - image: mailcow/acme:1.88 + image: mailcow/acme:1.89 dns: - ${IPV4_NETWORK:-172.22.1}.254 environment: From 2fe21e964126e0f4a251ad72443f21ef622c6edb Mon Sep 17 00:00:00 2001 From: Hassan A Hashim Date: Wed, 7 Aug 2024 14:57:36 +0300 Subject: [PATCH 109/138] Refactor: `update.sh` script with `--help` should exit with status code 0 --- update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update.sh b/update.sh index 38942cc5..b89514e5 100755 --- a/update.sh +++ b/update.sh @@ -409,7 +409,7 @@ while (($#)); do -f|--force - Force update, do not ask questions -d|--dev - Enables Developer Mode (No Checkout of update.sh for tests) ' - exit 1 + exit 0 esac shift done From 4b400eadb1112c07d8e6ac523cebf099912210e2 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 6 Jun 2024 10:30:59 +0200 Subject: [PATCH 110/138] rspamd: Added DQS RBLs when key is set --- data/Dockerfiles/rspamd/docker-entrypoint.sh | 188 ++++++++++++++ data/conf/rspamd/local.d/rbl.conf | 6 +- data/conf/rspamd/local.d/rbl_group.conf | 257 +++++++++++++++++++ 3 files changed, 450 insertions(+), 1 deletion(-) diff --git a/data/Dockerfiles/rspamd/docker-entrypoint.sh b/data/Dockerfiles/rspamd/docker-entrypoint.sh index 8af7619c..a6141c57 100755 --- a/data/Dockerfiles/rspamd/docker-entrypoint.sh +++ b/data/Dockerfiles/rspamd/docker-entrypoint.sh @@ -124,4 +124,192 @@ for file in /hooks/*; do fi done +# If DQS KEY is set in mailcow.conf add Spamhaus DQS RBLs +if [[ ! -z ${SPAMHAUS_DQS_KEY} ]]; then + cat < /etc/rspamd/custom/dqs-rbl.conf + # Autogenerated by mailcow. DO NOT TOUCH! + rbls { + spamhaus { + rbl = "${SPAMHAUS_DQS_KEY}.zen.dq.spamhaus.net"; + from = false; + } + spamhaus_from { + from = true; + received = false; + rbl = "${SPAMHAUS_DQS_KEY}.zen.dq.spamhaus.net"; + returncodes { + SPAMHAUS_ZEN = [ "127.0.0.2", "127.0.0.3", "127.0.0.4", "127.0.0.5", "127.0.0.6", "127.0.0.7", "127.0.0.9", "127.0.0.10", "127.0.0.11" ]; + } + } + spamhaus_authbl_received { + # Check if the sender client is listed in AuthBL (AuthBL is *not* part of ZEN) + rbl = "${SPAMHAUS_DQS_KEY}.authbl.dq.spamhaus.net"; + from = false; + received = true; + ipv6 = true; + returncodes { + SH_AUTHBL_RECEIVED = "127.0.0.20" + } + } + spamhaus_dbl { + # Add checks on the HELO string + rbl = "${SPAMHAUS_DQS_KEY}.dbl.dq.spamhaus.net"; + helo = true; + rdns = true; + dkim = true; + disable_monitoring = true; + returncodes { + RBL_DBL_SPAM = "127.0.1.2"; + RBL_DBL_PHISH = "127.0.1.4"; + RBL_DBL_MALWARE = "127.0.1.5"; + RBL_DBL_BOTNET = "127.0.1.6"; + RBL_DBL_ABUSED_SPAM = "127.0.1.102"; + RBL_DBL_ABUSED_PHISH = "127.0.1.104"; + RBL_DBL_ABUSED_MALWARE = "127.0.1.105"; + RBL_DBL_ABUSED_BOTNET = "127.0.1.106"; + RBL_DBL_DONT_QUERY_IPS = "127.0.1.255"; + } + } + spamhaus_dbl_fullurls { + ignore_defaults = true; + no_ip = true; + rbl = "${SPAMHAUS_DQS_KEY}.dbl.dq.spamhaus.net"; + selector = 'urls:get_host' + disable_monitoring = true; + returncodes { + DBLABUSED_SPAM_FULLURLS = "127.0.1.102"; + DBLABUSED_PHISH_FULLURLS = "127.0.1.104"; + DBLABUSED_MALWARE_FULLURLS = "127.0.1.105"; + DBLABUSED_BOTNET_FULLURLS = "127.0.1.106"; + } + } + spamhaus_zrd { + # Add checks on the HELO string also for DQS + rbl = "${SPAMHAUS_DQS_KEY}.zrd.dq.spamhaus.net"; + helo = true; + rdns = true; + dkim = true; + disable_monitoring = true; + returncodes { + RBL_ZRD_VERY_FRESH_DOMAIN = ["127.0.2.2", "127.0.2.3", "127.0.2.4"]; + RBL_ZRD_FRESH_DOMAIN = [ + "127.0.2.5", "127.0.2.6", "127.0.2.7", "127.0.2.8", "127.0.2.9", "127.0.2.10", "127.0.2.11", "127.0.2.12", "127.0.2.13", "127.0.2.14", "127.0.2.15", "127.0.2.16", "127.0.2.17", "127.0.2.18", "127.0.2.19", "127.0.2.20", "127.0.2.21", "127.0.2.22", "127.0.2.23", "127.0.2.24" + ]; + RBL_ZRD_DONT_QUERY_IPS = "127.0.2.255"; + } + } + "SPAMHAUS_ZEN_URIBL" { + enabled = true; + rbl = "${SPAMHAUS_DQS_KEY}.zen.dq.spamhaus.net"; + resolve_ip = true; + checks = ['urls']; + replyto = true; + emails = true; + ipv4 = true; + ipv6 = true; + emails_domainonly = true; + returncodes { + URIBL_SBL = "127.0.0.2"; + URIBL_SBL_CSS = "127.0.0.3"; + URIBL_XBL = ["127.0.0.4", "127.0.0.5", "127.0.0.6", "127.0.0.7"]; + URIBL_PBL = ["127.0.0.10", "127.0.0.11"]; + URIBL_DROP = "127.0.0.9"; + } + } + SH_EMAIL_DBL { + ignore_defaults = true; + replyto = true; + emails_domainonly = true; + disable_monitoring = true; + rbl = "${SPAMHAUS_DQS_KEY}.dbl.dq.spamhaus.net" + returncodes = { + SH_EMAIL_DBL = [ + "127.0.1.2", + "127.0.1.4", + "127.0.1.5", + "127.0.1.6" + ]; + SH_EMAIL_DBL_ABUSED = [ + "127.0.1.102", + "127.0.1.104", + "127.0.1.105", + "127.0.1.106" + ]; + SH_EMAIL_DBL_DONT_QUERY_IPS = [ "127.0.1.255" ]; + } + } + SH_EMAIL_ZRD { + ignore_defaults = true; + replyto = true; + emails_domainonly = true; + disable_monitoring = true; + rbl = "${SPAMHAUS_DQS_KEY}.zrd.dq.spamhaus.net" + returncodes = { + SH_EMAIL_ZRD_VERY_FRESH_DOMAIN = ["127.0.2.2", "127.0.2.3", "127.0.2.4"]; + SH_EMAIL_ZRD_FRESH_DOMAIN = [ + "127.0.2.5", "127.0.2.6", "127.0.2.7", "127.0.2.8", "127.0.2.9", "127.0.2.10", "127.0.2.11", "127.0.2.12", "127.0.2.13", "127.0.2.14", "127.0.2.15", "127.0.2.16", "127.0.2.17", "127.0.2.18", "127.0.2.19", "127.0.2.20", "127.0.2.21", "127.0.2.22", "127.0.2.23", "127.0.2.24" + ]; + SH_EMAIL_ZRD_DONT_QUERY_IPS = [ "127.0.2.255" ]; + } + } + "DBL" { + # override the defaults for DBL defined in modules.d/rbl.conf + rbl = "${SPAMHAUS_DQS_KEY}.dbl.dq.spamhaus.net"; + disable_monitoring = true; + } + "ZRD" { + ignore_defaults = true; + rbl = "${SPAMHAUS_DQS_KEY}.zrd.dq.spamhaus.net"; + no_ip = true; + dkim = true; + emails = true; + emails_domainonly = true; + urls = true; + returncodes = { + ZRD_VERY_FRESH_DOMAIN = ["127.0.2.2", "127.0.2.3", "127.0.2.4"]; + ZRD_FRESH_DOMAIN = ["127.0.2.5", "127.0.2.6", "127.0.2.7", "127.0.2.8", "127.0.2.9", "127.0.2.10", "127.0.2.11", "127.0.2.12", "127.0.2.13", "127.0.2.14", "127.0.2.15", "127.0.2.16", "127.0.2.17", "127.0.2.18", "127.0.2.19", "127.0.2.20", "127.0.2.21", "127.0.2.22", "127.0.2.23", "127.0.2.24"]; + } + } + spamhaus_sbl_url { + ignore_defaults = true + rbl = "${SPAMHAUS_DQS_KEY}.sbl.dq.spamhaus.net"; + checks = ['urls']; + disable_monitoring = true; + returncodes { + SPAMHAUS_SBL_URL = "127.0.0.2"; + } + } + + SH_HBL_EMAIL { + ignore_defaults = true; + rbl = "_email.${SPAMHAUS_DQS_KEY}.hbl.dq.spamhaus.net"; + emails_domainonly = false; + selector = "from('smtp').lower;from('mime').lower"; + ignore_whitelist = true; + checks = ['emails', 'replyto']; + hash = "sha1"; + returncodes = { + SH_HBL_EMAIL = [ + "127.0.3.2" + ]; + } + } + + spamhaus_dqs_hbl { + symbol = "HBL_FILE_UNKNOWN"; + rbl = "_file.${SPAMHAUS_DQS_KEY}.hbl.dq.spamhaus.net."; + selector = "attachments('rbase32', 'sha256')"; + ignore_whitelist = true; + ignore_defaults = true; + returncodes { + SH_HBL_FILE_MALICIOUS = "127.0.3.10"; + SH_HBL_FILE_SUSPICIOUS = "127.0.3.15"; + } + } + } +EOF +else + rm -rf /etc/rspamd/custom/dqs-rbl.conf +fi + exec "$@" diff --git a/data/conf/rspamd/local.d/rbl.conf b/data/conf/rspamd/local.d/rbl.conf index d49dae03..509435d5 100644 --- a/data/conf/rspamd/local.d/rbl.conf +++ b/data/conf/rspamd/local.d/rbl.conf @@ -2,6 +2,7 @@ rbls { interserver_ip { symbol = "RBL_INTERSERVER_IP"; rbl = "rbl.interserver.net"; + from = true; ipv6 = false; returncodes { RBL_INTERSERVER_BAD_IP = "127.0.0.2"; @@ -19,4 +20,7 @@ rbls { RBL_INTERSERVER_BAD_URI = "127.0.0.2"; } } -} + +.include(try=true,priority=5) "$LOCAL_CONFDIR/custom/dqs-rbl.conf" + +} \ No newline at end of file diff --git a/data/conf/rspamd/local.d/rbl_group.conf b/data/conf/rspamd/local.d/rbl_group.conf index 4d346f15..916de4ef 100644 --- a/data/conf/rspamd/local.d/rbl_group.conf +++ b/data/conf/rspamd/local.d/rbl_group.conf @@ -17,4 +17,261 @@ symbols = { score = 4.0; description = "Listed on Interserver RBL"; } + + "SPAMHAUS_ZEN" { + weight = 7.0; + } + "SH_AUTHBL_RECEIVED" { + weight = 4.0; + } + "RBL_DBL_SPAM" { + weight = 7.0; + } + "RBL_DBL_PHISH" { + weight = 7.0; + } + "RBL_DBL_MALWARE" { + weight = 7.0; + } + "RBL_DBL_BOTNET" { + weight = 7.0; + } + "RBL_DBL_ABUSED_SPAM" { + weight = 3.0; + } + "RBL_DBL_ABUSED_PHISH" { + weight = 3.0; + } + "RBL_DBL_ABUSED_MALWARE" { + weight = 3.0; + } + "RBL_DBL_ABUSED_BOTNET" { + weight = 3.0; + } + "RBL_ZRD_VERY_FRESH_DOMAIN" { + weight = 7.0; + } + "RBL_ZRD_FRESH_DOMAIN" { + weight = 4.0; + } + "ZRD_VERY_FRESH_DOMAIN" { + weight = 7.0; + } + "ZRD_FRESH_DOMAIN" { + weight = 4.0; + } + "SH_EMAIL_DBL" { + weight = 7.0; + } + "SH_EMAIL_DBL_ABUSED" { + weight = 7.0; + } + "SH_EMAIL_ZRD_VERY_FRESH_DOMAIN" { + weight = 7.0; + } + "SH_EMAIL_ZRD_FRESH_DOMAIN" { + weight = 4.0; + } + "RBL_DBL_DONT_QUERY_IPS" { + weight = 0.0; + } + "RBL_ZRD_DONT_QUERY_IPS" { + weight = 0.0; + } + "SH_EMAIL_ZRD_DONT_QUERY_IPS" { + weight = 0.0; + } + "SH_EMAIL_DBL_DONT_QUERY_IPS" { + weight = 0.0; + } + "DBL" { + weight = 0.0; + description = "DBL unknown result"; + groups = ["spamhaus"]; + } + "DBL_SPAM" { + weight = 7; + description = "DBL uribl spam"; + groups = ["spamhaus"]; + } + "DBL_PHISH" { + weight = 7; + description = "DBL uribl phishing"; + groups = ["spamhaus"]; + } + "DBL_MALWARE" { + weight = 7; + description = "DBL uribl malware"; + groups = ["spamhaus"]; + } + "DBL_BOTNET" { + weight = 7; + description = "DBL uribl botnet C&C domain"; + groups = ["spamhaus"]; + } + + + "DBLABUSED_SPAM_FULLURLS" { + weight = 5.5; + description = "DBL uribl abused legit spam"; + groups = ["spamhaus"]; + } + "DBLABUSED_PHISH_FULLURLS" { + weight = 5.5; + description = "DBL uribl abused legit phish"; + groups = ["spamhaus"]; + } + "DBLABUSED_MALWARE_FULLURLS" { + weight = 5.5; + description = "DBL uribl abused legit malware"; + groups = ["spamhaus"]; + } + "DBLABUSED_BOTNET_FULLURLS" { + weight = 5.5; + description = "DBL uribl abused legit botnet"; + groups = ["spamhaus"]; + } + + "DBL_ABUSE" { + weight = 5.5; + description = "DBL uribl abused legit spam"; + groups = ["spamhaus"]; + } + "DBL_ABUSE_REDIR" { + weight = 1.5; + description = "DBL uribl abused spammed redirector domain"; + groups = ["spamhaus"]; + } + "DBL_ABUSE_PHISH" { + weight = 5.5; + description = "DBL uribl abused legit phish"; + groups = ["spamhaus"]; + } + "DBL_ABUSE_MALWARE" { + weight = 5.5; + description = "DBL uribl abused legit malware"; + groups = ["spamhaus"]; + } + "DBL_ABUSE_BOTNET" { + weight = 5.5; + description = "DBL uribl abused legit botnet C&C"; + groups = ["spamhaus"]; + } + "DBL_PROHIBIT" { + weight = 0.0; + description = "DBL uribl IP queries prohibited!"; + groups = ["spamhaus"]; + } + "DBL_BLOCKED_OPENRESOLVER" { + weight = 0.0; + description = "You are querying Spamhaus from an open resolver, please see https://www.spamhaus.org/returnc/pub/"; + groups = ["spamhaus"]; + } + "DBL_BLOCKED" { + weight = 0.0; + description = "You are exceeding the query limit, please see https://www.spamhaus.org/returnc/vol/"; + groups = ["spamhaus"]; + } + "SPAMHAUS_ZEN_URIBL" { + weight = 0.0; + description = "Spamhaus ZEN URIBL: Filtered result"; + groups = ["spamhaus"]; + } + "URIBL_SBL" { + weight = 6.5; + description = "A domain in the message body resolves to an IP listed in Spamhaus SBL"; + one_shot = true; + groups = ["spamhaus"]; + } + "URIBL_SBL_CSS" { + weight = 6.5; + description = "A domain in the message body resolves to an IP listed in Spamhaus SBL CSS"; + one_shot = true; + groups = ["spamhaus"]; + } + "URIBL_PBL" { + weight = 0.01; + description = "A domain in the message body resolves to an IP listed in Spamhaus PBL"; + one_shot = true; + groups = ["spamhaus"]; + } + "URIBL_DROP" { + weight = 6.5; + description = "A domain in the message body resolves to an IP listed in Spamhaus DROP"; + one_shot = true; + groups = ["spamhaus"]; + } + "URIBL_XBL" { + weight = 5.0; + description = "A domain in the message body resolves to an IP listed in Spamhaus XBL"; + one_shot = true; + groups = ["spamhaus"]; + } + "SPAMHAUS_SBL_URL" { + weight = 6.5; + description = "A numeric URL in the message body is listed in Spamhaus SBL"; + one_shot = true; + groups = ["spamhaus"]; + } + + "SH_HBL_EMAIL" { + weight = 7; + description = "Email listed in HBL"; + groups = ["spamhaus"]; + } + + "SH_HBL_FILE_MALICIOUS" { + weight = 7; + description = "An attachment hash is listed in Spamhaus HBL as malicious"; + groups = ["spamhaus"]; + } + + "SH_HBL_FILE_SUSPICIOUS" { + weight = 5; + description = "An attachment hash is listed in Spamhaus HBL as suspicious"; + groups = ["spamhaus"]; + } + + "RBL_SPAMHAUS_CW_BTC" { + score = 7; + description = "Bitcoin found in Spamhaus cryptowallet list"; + groups = ["spamhaus"]; + } + + "RBL_SPAMHAUS_CW_ETH" { + score = 7; + description = "Ethereum found in Spamhaus cryptowallet list"; + groups = ["spamhaus"]; + } + + "RBL_SPAMHAUS_CW_BCH" { + score = 7; + description = "Bitcoinhash found in Spamhaus cryptowallet list"; + groups = ["spamhaus"]; + } + + "RBL_SPAMHAUS_CW_XMR" { + score = 7; + description = "Monero found in Spamhaus cryptowallet list"; + groups = ["spamhaus"]; + } + + "RBL_SPAMHAUS_CW_LTC" { + score = 7; + description = "Litecoin found in Spamhaus cryptowallet list"; + groups = ["spamhaus"]; + } + + "RBL_SPAMHAUS_CW_XRP" { + score = 7; + description = "Ripple found in Spamhaus cryptowallet list"; + groups = ["spamhaus"]; + } + + "RBL_SPAMHAUS_HBL_URL" { + score = 7; + description = "URL found in spamhaus HBL blocklist"; + groups = ["spamhaus"]; + } + } From 5d7c9b20bc2fe101ab7da37f768d0812aec37e02 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 1 Aug 2024 12:37:31 +0200 Subject: [PATCH 111/138] rspamd: upgrade to 3.9.1 + upgrade to bookworm --- data/Dockerfiles/rspamd/Dockerfile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/data/Dockerfiles/rspamd/Dockerfile b/data/Dockerfiles/rspamd/Dockerfile index 76956244..df15a0be 100644 --- a/data/Dockerfiles/rspamd/Dockerfile +++ b/data/Dockerfiles/rspamd/Dockerfile @@ -1,11 +1,10 @@ -FROM debian:bullseye-slim - +FROM debian:bookworm-slim LABEL maintainer = "The Infrastructure Company GmbH " ARG DEBIAN_FRONTEND=noninteractive -ARG RSPAMD_VER=rspamd_3.7.5-2~8c86c1676 -ARG CODENAME=bullseye -ENV LC_ALL C +ARG RSPAMD_VER=rspamd_3.9.1-1~82f43560f +ARG CODENAME=bookworm +ENV LC_ALL=C RUN apt-get update && apt-get install -y \ tzdata \ @@ -13,11 +12,12 @@ RUN apt-get update && apt-get install -y \ gnupg2 \ apt-transport-https \ dnsutils \ - netcat \ + netcat-traditional \ wget \ redis-tools \ procps \ nano \ + lua-cjson \ && arch=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) \ && wget -P /tmp https://rspamd.com/apt-stable/pool/main/r/rspamd/${RSPAMD_VER}~${CODENAME}_${arch}.deb\ && apt install -y /tmp/${RSPAMD_VER}~${CODENAME}_${arch}.deb \ From b6c036496d03634c48cd953d09aeba67bf19a29d Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 1 Aug 2024 12:37:49 +0200 Subject: [PATCH 112/138] rspamd: fixed dqs rbl insertion handling --- data/Dockerfiles/rspamd/docker-entrypoint.sh | 46 ++++++++++---------- data/conf/rspamd/local.d/rbl.conf | 2 +- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/data/Dockerfiles/rspamd/docker-entrypoint.sh b/data/Dockerfiles/rspamd/docker-entrypoint.sh index a6141c57..cf09ee48 100755 --- a/data/Dockerfiles/rspamd/docker-entrypoint.sh +++ b/data/Dockerfiles/rspamd/docker-entrypoint.sh @@ -128,7 +128,6 @@ done if [[ ! -z ${SPAMHAUS_DQS_KEY} ]]; then cat < /etc/rspamd/custom/dqs-rbl.conf # Autogenerated by mailcow. DO NOT TOUCH! - rbls { spamhaus { rbl = "${SPAMHAUS_DQS_KEY}.zen.dq.spamhaus.net"; from = false; @@ -221,7 +220,7 @@ if [[ ! -z ${SPAMHAUS_DQS_KEY} ]]; then replyto = true; emails_domainonly = true; disable_monitoring = true; - rbl = "${SPAMHAUS_DQS_KEY}.dbl.dq.spamhaus.net" + rbl = "${SPAMHAUS_DQS_KEY}.dbl.dq.spamhaus.net"; returncodes = { SH_EMAIL_DBL = [ "127.0.1.2", @@ -243,7 +242,7 @@ if [[ ! -z ${SPAMHAUS_DQS_KEY} ]]; then replyto = true; emails_domainonly = true; disable_monitoring = true; - rbl = "${SPAMHAUS_DQS_KEY}.zrd.dq.spamhaus.net" + rbl = "${SPAMHAUS_DQS_KEY}.zrd.dq.spamhaus.net"; returncodes = { SH_EMAIL_ZRD_VERY_FRESH_DOMAIN = ["127.0.2.2", "127.0.2.3", "127.0.2.4"]; SH_EMAIL_ZRD_FRESH_DOMAIN = [ @@ -251,26 +250,26 @@ if [[ ! -z ${SPAMHAUS_DQS_KEY} ]]; then ]; SH_EMAIL_ZRD_DONT_QUERY_IPS = [ "127.0.2.255" ]; } - } - "DBL" { - # override the defaults for DBL defined in modules.d/rbl.conf - rbl = "${SPAMHAUS_DQS_KEY}.dbl.dq.spamhaus.net"; - disable_monitoring = true; - } - "ZRD" { - ignore_defaults = true; - rbl = "${SPAMHAUS_DQS_KEY}.zrd.dq.spamhaus.net"; - no_ip = true; - dkim = true; - emails = true; - emails_domainonly = true; - urls = true; - returncodes = { - ZRD_VERY_FRESH_DOMAIN = ["127.0.2.2", "127.0.2.3", "127.0.2.4"]; - ZRD_FRESH_DOMAIN = ["127.0.2.5", "127.0.2.6", "127.0.2.7", "127.0.2.8", "127.0.2.9", "127.0.2.10", "127.0.2.11", "127.0.2.12", "127.0.2.13", "127.0.2.14", "127.0.2.15", "127.0.2.16", "127.0.2.17", "127.0.2.18", "127.0.2.19", "127.0.2.20", "127.0.2.21", "127.0.2.22", "127.0.2.23", "127.0.2.24"]; - } - } - spamhaus_sbl_url { + } + "DBL" { + # override the defaults for DBL defined in modules.d/rbl.conf + rbl = "${SPAMHAUS_DQS_KEY}.dbl.dq.spamhaus.net"; + disable_monitoring = true; + } + "ZRD" { + ignore_defaults = true; + rbl = "${SPAMHAUS_DQS_KEY}.zrd.dq.spamhaus.net"; + no_ip = true; + dkim = true; + emails = true; + emails_domainonly = true; + urls = true; + returncodes = { + ZRD_VERY_FRESH_DOMAIN = ["127.0.2.2", "127.0.2.3", "127.0.2.4"]; + ZRD_FRESH_DOMAIN = ["127.0.2.5", "127.0.2.6", "127.0.2.7", "127.0.2.8", "127.0.2.9", "127.0.2.10", "127.0.2.11", "127.0.2.12", "127.0.2.13", "127.0.2.14", "127.0.2.15", "127.0.2.16", "127.0.2.17", "127.0.2.18", "127.0.2.19", "127.0.2.20", "127.0.2.21", "127.0.2.22", "127.0.2.23", "127.0.2.24"]; + } + } + spamhaus_sbl_url { ignore_defaults = true rbl = "${SPAMHAUS_DQS_KEY}.sbl.dq.spamhaus.net"; checks = ['urls']; @@ -306,7 +305,6 @@ if [[ ! -z ${SPAMHAUS_DQS_KEY} ]]; then SH_HBL_FILE_SUSPICIOUS = "127.0.3.15"; } } - } EOF else rm -rf /etc/rspamd/custom/dqs-rbl.conf diff --git a/data/conf/rspamd/local.d/rbl.conf b/data/conf/rspamd/local.d/rbl.conf index 509435d5..7f2976a0 100644 --- a/data/conf/rspamd/local.d/rbl.conf +++ b/data/conf/rspamd/local.d/rbl.conf @@ -21,6 +21,6 @@ rbls { } } -.include(try=true,priority=5) "$LOCAL_CONFDIR/custom/dqs-rbl.conf" +.include(try=true,override=true,priority=5) "$LOCAL_CONFDIR/custom/dqs-rbl.conf" } \ No newline at end of file From 6e00d653ce64d17092fa86c178509900aa84821b Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 1 Aug 2024 12:38:00 +0200 Subject: [PATCH 113/138] compose: bumped rspamd tag --- docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index b5875481..baec698e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -80,7 +80,7 @@ services: - clamd rspamd-mailcow: - image: mailcow/rspamd:1.96 + image: mailcow/rspamd:1.97 stop_grace_period: 30s depends_on: - dovecot-mailcow @@ -90,6 +90,7 @@ services: - IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64} - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-} - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-} + - SPAMHAUS_DQS_KEY=${SPAMHAUS_DQS_KEY:-} volumes: - ./data/hooks/rspamd:/hooks:Z - ./data/conf/rspamd/custom/:/etc/rspamd/custom:z From 52431a39425c90db35bb2a76a0078ac050fd42cb Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Wed, 7 Aug 2024 14:50:12 +0200 Subject: [PATCH 114/138] compose: bump watchdog image --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 9257fe35..e1b9f0fc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -462,7 +462,7 @@ services: - /lib/modules:/lib/modules:ro watchdog-mailcow: - image: mailcow/watchdog:2.03 + image: mailcow/watchdog:2.04 dns: - ${IPV4_NETWORK:-172.22.1}.254 tmpfs: From 7f790c5360bd40b534afd96b67ef2d127e63344a Mon Sep 17 00:00:00 2001 From: milkmaker Date: Wed, 7 Aug 2024 18:39:38 +0200 Subject: [PATCH 115/138] [Web] Updated lang.si-si.json (#5995) Co-authored-by: gomiunik --- data/web/lang/lang.si-si.json | 114 ++++++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 5 deletions(-) diff --git a/data/web/lang/lang.si-si.json b/data/web/lang/lang.si-si.json index 3a424631..e9468e0c 100644 --- a/data/web/lang/lang.si-si.json +++ b/data/web/lang/lang.si-si.json @@ -107,7 +107,8 @@ "post_domain_add": "SOGo container \"sogo-mailcow\" mora biti ponovno zagnan po dodajanju nove domene!

Dodatno se mora preveriti DNS konfiguracija domene. Ko je DNS konfiguracija domene odobrena, ponovno zaženite \"acme-mailcow\" za samodejno generiranje certifikatov za novo domeno (autoconfig.<domain>, autodiscover.<domain>).
Ta korak je opcijski in se ponovno poskuša vsakih 24 ur.", "relay_transport_info": "
Info
Definirate lahko preslikave transportov za cilj po meri za to domeno. Če ni nastavljena, se ustvari MX poizvedba.", "syncjob_hint": "Pozor! Gesla se morajo shraniti v plain-text!", - "timeout2": "Časovna omejitev za povezavo do lokalnega gostitelja" + "timeout2": "Časovna omejitev za povezavo do lokalnega gostitelja", + "dry": "Simuliraj sinhronizacijo" }, "admin": { "access": "Dostop", @@ -347,7 +348,10 @@ "logo_dark_label": "Za temni način", "cors_settings": "Nastavitve CORS", "allowed_methods": "Dovoljene metode za upravljanje dostopa", - "allowed_origins": "Upravljanje-dostopa-Dovoljeni-Viri" + "allowed_origins": "Upravljanje-dostopa-Dovoljeni-Viri", + "copy_to_clipboard": "Besedilo kopirano v odložišče!", + "f2b_manage_external": "Zunanje upravljanje Fail2Ban", + "f2b_manage_external_info": "Fail2ban bo še vedno vzdrževal seznam prepovedi, vendar ne bo aktivno nastavil pravil za blokiranje prometa. Uporabite spodnji ustvarjeni seznam prepovedi za zunanje blokiranje prometa." }, "danger": { "alias_goto_identical": "Alias in goto naslov morata biti identična", @@ -476,7 +480,9 @@ "temp_error": "Začasna napaka", "cors_invalid_method": "Navedena neveljavna Allow metoda", "cors_invalid_origin": "Naveden neveljaven Allow-Origin", - "invalid_recipient_map_new": "Naveden neveljaven nov prejemnik: %s" + "invalid_recipient_map_new": "Naveden neveljaven nov prejemnik: %s", + "img_dimensions_exceeded": "Slika presega največje dovoljene dimenzije", + "img_size_exceeded": "Slika presega največjo dovoljeno velikost datoteke" }, "debug": { "containers_info": "Informacije o vsebniku (containerju)", @@ -511,7 +517,13 @@ "no_update_available": "Sistem je na najnovejši verziji", "update_failed": "Ni mogoče preveriti za posodobitve", "username": "Uporabniško ime", - "wip": "Trenutno v delu" + "wip": "Trenutno v delu", + "log_info": "

mailcow in-memory dnevniki se zbirajo v Redis seznamih in se vsako minuto omejijo na LOG_LINES (%d) da se zmanjša obremenitev.\n
In-memory dnevniki niso namenjeni trajnemu shranjevanju. Vse aplikacije, ki beležijo dnevnike in-memory, tudi beležijo v Docker daemon in posledično v privzeti gonilnik za dnevnik.\n
In-memory dnevniki se naj uporabljajo za odpravljanje manjših napak s containerji.

\n

Eksterni dnevniki se zbirajo preko API-ja posamezne aplikacije.

\n

Statični dnevniki so večinoma dnevniki aktivnosti, ki se ne beležijo v Dockerd, a jih je vseeno treba hraniti (razen API dnevnikov).

", + "login_time": "Čas", + "logs": "Dnevniki", + "memory": "Spomin", + "online_users": "Prijavljeni uporabniki", + "restart_container": "Ponovno zaženi" }, "datatables": { "infoFiltered": "(filtrirano od _MAX_ skupaj zapisov)", @@ -551,6 +563,98 @@ }, "edit": { "acl": "ACL (Dovoljenje)", - "active": "Aktivno" + "active": "Aktivno", + "allow_from_smtp": "Dovoli samo tem IP naslovom da uporabijo SMTP", + "bcc_dest_format": "Cilj BCC mora biti en veljaven email naslov.
Če morate poslati kopijo na več naslovov, ustvarite alias in ga uporabite tukaj.", + "automap": "Poskušaj samodejno preslikati mape (\"Sent items\", \"Sent\" => \"Poslano\" ipd.)", + "admin": "Uredi skrbnika", + "domain_footer_info_vars": { + "custom": "{= foo =} - Če ima poštni predal atribut po meri \"foo\" z vrednostjo \"bar\", spremenljivka vrne \"bar\"", + "auth_user": "{= auth_user =} - Prijavljeno uporabniško ime, ki ga določi MTA", + "from_user": "{= from_user =} - leva stran email naslova uporabnika, npr. za \"moo@mailcow.tld\" vrne \"moo\"", + "from_name": "{= from_name =} - Prikazno ime, npr. za \"Mailcow <moo@mailcow.tld>\" vrne \"Mailcow\"", + "from_addr": "{= from_addr =} - e-poštni naslov \"Od\"", + "from_domain": "{= from_domain =} - domena e-poštnega naslova \"Od\"" + }, + "dont_check_sender_acl": "Onemogoči kontrolo pošiljatelja za domeno %s (+ alias domene)", + "pushover_title": "Naslov obvestila", + "domains": "Domene", + "extended_sender_acl_info": "Če je DKIM domenski ključ na voljo, ga uvozite.
\n Ne pozabite dodati ta strežnik k ustreznemu SPF TXT zapisu.
\n Kadar koli je domena ali alias domena dodana k tem strežniku, ki se prekriva z zunanjim naslovom, je zunanji naslov odstranjen.
\n uporabite @domain.tld da dovolite pošiljanje kot *@domain.tld.", + "lookup_mx": "Cilj je regular expression za ujemanje MX zapisov (.*\\.google\\.com za usmeritev vse pošte na MX, ki se konča z google.com, preko tega skoka)", + "maxbytespersecond": "Največ bytov na sekundo
(0 = neomejeno)", + "pushover_sender_array": "Upoštevaj samo sledeče e-poštne naslove pošiljateljev (ločeni z vejico)", + "mbox_rl_info": "Ta omejitev velja za SASL uporabniško ime, preverja se ujemanje s katerim koli \"from\" naslovom, ki ga uporablja prijavljeni uporabnik. Omejitev pošiljanja za poštni predal preglasi pravilo omejitve za domeno.", + "kind": "Tip", + "client_secret": "Client secret", + "comment_info": "Zasebni komentar ni viden uporabniku, javni komentar pa je viden kot tooltip v uporabnikovem pregledu.", + "created_on": "Ustvarjeno", + "custom_attributes": "Atributi po meri", + "delete1": "Izbriši na viru, ko je končano", + "delete2": "Izbriši sporočila na cilju, ki ne obstajajo na viru", + "delete2duplicates": "Izbriši dvojnike na cilju", + "delete_ays": "Prosim potrdite proces izbrisa.", + "description": "Opis", + "disable_login": "Onemogoči prijavo (dohodna pošta je še vedno sprejeta)", + "domain": "Uredi domeno", + "domain_admin": "Uredi domenskega skrbnika", + "domain_footer": "Noga za celo domeno", + "domain_footer_html": "HTML noga", + "pushover_vars": "Če ni definiran noben filter pošiljatelja, bodo upoštevana vsa sporočila.
Regex filtre in natančna preverjanja pošiljateljev je mogoče definirati posamezno in bodo obravnavani v nadaljevanju. Niso odvisni drug od drugega.
Uporabne spremenljivke za besedilo in naslov (prosimo, upoštevajte politike varstva podatkov)", + "pushover_verify": "Preveri poverilnice", + "quota_mb": "Omejitev (MiB)", + "quota_warning_bcc": "BCC za sporočilo z opozorilom omejitve", + "quota_warning_bcc_info": "Opozorila bodo poslana kot ločene kopije sledečim prejemnikom. K naslovu sporočila bo dodano uporabniško ime v oklepajih, npr. Opozorilo omejitve (user@example.com)", + "ratelimit": "Omejitev pošiljanja", + "advanced_settings": "Napredne nastavitve", + "allow_from_smtp_info": "Pustite prazno da dovolite vse pošiljatelje.
IPv4/IPv6 naslovi in omrežja.", + "allowed_protocols": "Dovoljeni protokoli", + "app_name": "Ime aplikacije", + "app_passwd": "Geslo aplikacije", + "app_passwd_protocols": "Dovoljeni protokoli za geslo aplikacije", + "backup_mx_options": "Možnosti posredovanja (relay)", + "client_id": "Client ID", + "domain_footer_info": "Noge za celo domeno so dodane k vsem izhodnim e-poštnim sporočilom v tej domeni.
V nogi se lahko uporabijo sledeče spremenljivke:", + "domain_footer_plain": "PLAIN noga", + "domain_footer_skip_replies": "Ne dodajaj noge v odgovorih na e-poštna sporočila", + "domain_quota": "Omejitev (kvota) domene", + "edit_alias_domain": "Uredi alias domeno", + "exclude": "Izključi objekte (regex)", + "extended_sender_acl": "Naslovi zunanjih pošiljateljev", + "force_pw_update": "Obvezna zamenjava gesla ob naslednji prijavi", + "force_pw_update_info": "Ta uporabnik se bo lahko prijavil samo v %s. Gesla aplikacij ostajajo v rabi.", + "footer_exclude": "Izključi iz noge", + "full_name": "Polno ime", + "gal": "Globalni seznam naslovov (GAL)", + "gal_info": "GAL vsebuje vse objekte v domeni in jih uporabniki ne morejo urejati. Če je onemogočeno, ni podatkov o o zasedenosti objekta! Ponovno zaženite SOGo za uveljavitev sprememb.", + "generate": "generiraj", + "grant_types": "Vrste dovoljenj", + "hostname": "Ime gostitelja", + "inactive": "Neaktivno", + "last_modified": "Nazadnje spremenjeno", + "mailbox": "Uredi poštni predal", + "mailbox_quota_def": "Privzeta omejitev/kvota za poštni predal", + "mailbox_relayhost_info": "Velja samo za poštni predal in neposredne aliase. Ne prepiše domenskega relay gostitelja.", + "max_aliases": "Največ aliasov", + "max_mailboxes": "Največ možnih poštnih predalov", + "max_quota": "Največja omejitev/kvota na poštni predal (MiB)", + "maxage": "Največja starost sporočil (v dnevih), po katerih bo poizvedeno iz oddaljenega vira
(0 = ne omejuj)", + "mins_interval": "Interval (min)", + "multiple_bookings": "Več rezervacij", + "none_inherit": "Brez / podeduj", + "nexthop": "Naslednji skok", + "password": "Geslo", + "password_repeat": "Potrditev gesla (ponovite)", + "previous": "Prejšnja stran", + "private_comment": "Zasebni komentar", + "public_comment": "Javni komentar", + "pushover": "Pushover", + "pushover_evaluate_x_prio": "Eskaliraj visoko prednostno pošto [X-Priority: 1]", + "pushover_info": "Nastavitve potisnih obvestil bodo veljala za vsa čisto (ne spam) elektronsko pošto dostavljeno v %s vključno z aliasi (deljeni, nedeljeni, označeni)", + "pushover_only_x_prio": "Upoštevaj samo pošto z visoko prioriteto [X-Priority: 1]", + "pushover_sender_regex": "Upoštevaj sledeči regex za pošiljatelja", + "pushover_text": "Besedilo obvestila", + "pushover_sound": "Zvok", + "encryption": "Šifriranje", + "alias": "Uredi alias" } } From 824a473fea3227a82e4bfc1f135b7d1459691fcb Mon Sep 17 00:00:00 2001 From: Kitof Date: Thu, 8 Aug 2024 08:42:50 +0200 Subject: [PATCH 116/138] ofelia: limit scope to mailcow project (#5776) * Filter to limit ofelia scope See https://github.com/mailcow/mailcow-dockerized/issues/5775 * compose: added ${COMPOSE_PROJECT_NAME} ENV to ofelia container --- docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index e1b9f0fc..a0fb03dc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -594,9 +594,10 @@ services: ofelia-mailcow: image: mcuadros/ofelia:latest restart: always - command: daemon --docker + command: daemon --docker -f label=com.docker.compose.project=${COMPOSE_PROJECT_NAME} environment: - TZ=${TZ} + - COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME} depends_on: - sogo-mailcow - dovecot-mailcow From 294a406b91b44d9519cdb2ef0282cbedebdf3788 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 8 Aug 2024 09:25:52 +0200 Subject: [PATCH 117/138] fix: disabled api call to solr in ui when mailbox deleted but using flatcurve --- data/web/inc/functions.mailbox.inc.php | 2 +- docker-compose.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 00c11dee..ff8d56e2 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -5212,7 +5212,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { 'msg' => 'Could not move maildir to garbage collector: variables local_part and/or domain empty' ); } - if (strtolower(getenv('SKIP_SOLR')) == 'n') { + if (strtolower(getenv('SKIP_SOLR')) == 'n' && strtolower(getenv('FLATCURVE_EXPERIMENTAL')) != 'y') { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, 'http://solr:8983/solr/dovecot-fts/update?commit=true'); curl_setopt($curl, CURLOPT_HTTPHEADER,array('Content-Type: text/xml')); diff --git a/docker-compose.yml b/docker-compose.yml index a0fb03dc..0f96aeac 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -168,6 +168,7 @@ services: - DEMO_MODE=${DEMO_MODE:-n} - WEBAUTHN_ONLY_TRUSTED_VENDORS=${WEBAUTHN_ONLY_TRUSTED_VENDORS:-n} - CLUSTERMODE=${CLUSTERMODE:-} + - FLATCURVE_EXPERIMENTAL=${FLATCURVE_EXPERIMENTAL:-} restart: always networks: mailcow-network: From 9fee5680827d9a95e5b33a5cb64d3524ff785ee3 Mon Sep 17 00:00:00 2001 From: milkmaker Date: Sat, 10 Aug 2024 20:44:40 +0200 Subject: [PATCH 118/138] Translations update from Weblate (#5999) * [Web] Updated lang.ru-ru.json Co-authored-by: Oleksii Kruhlenko * [Web] Updated lang.uk-ua.json Co-authored-by: Oleksii Kruhlenko --------- Co-authored-by: Oleksii Kruhlenko --- data/web/lang/lang.ru-ru.json | 14 +++++++------- data/web/lang/lang.uk-ua.json | 11 ++++++----- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/data/web/lang/lang.ru-ru.json b/data/web/lang/lang.ru-ru.json index db52dced..21775cb1 100644 --- a/data/web/lang/lang.ru-ru.json +++ b/data/web/lang/lang.ru-ru.json @@ -2,7 +2,7 @@ "acl": { "alias_domains": "Создание псевдонимов домена", "app_passwds": "Пароли приложений", - "bcc_maps": "Правила BBC", + "bcc_maps": "Правила BCC", "delimiter_action": "Обработка тегированной почты", "domain_desc": "Изменение описания домена", "domain_relayhost": "Изменение промежуточных узлов для домена", @@ -389,7 +389,7 @@ "imagick_exception": "Ошибка в Imagick при чтении изображения", "img_invalid": "Невозможно проверить файл изображения", "img_tmp_missing": "Невозможно проверить файл изображения: временный файл не найден", - "invalid_bcc_map_type": "Неверный тип правила BBC", + "invalid_bcc_map_type": "Неверный тип правила BCC", "invalid_destination": "Назначение \"%s\" указано неверно", "invalid_filter_type": "Неверный тип фильтра", "invalid_host": "Хост %s указан неверно", @@ -523,7 +523,7 @@ "app_passwd": "Пароль приложения", "automap": "Автоматическое слияние папок (\"Sent items\", \"Sent\" => \"Sent\" etc.)", "backup_mx_options": "Параметры резервного копирования MX", - "bcc_dest_format": "Назначением для правила BBC должен быть единственный действительный адрес электронной почты.", + "bcc_dest_format": "Назначением для правила BCC должен быть единственный действительный адрес электронной почты.", "client_id": "ID клиента", "client_secret": "Секретный ключ пользователя", "comment_info": "Приватный комментарий не виден пользователям, а публичный - отображается рядом с псевдонимом в личном кабинете пользователя", @@ -700,7 +700,7 @@ "add": "Добавить", "add_alias": "Добавить псевдоним", "add_alias_expand": "Скопировать псевдонимы на псевдонимы домена", - "add_bcc_entry": "Добавить правило BBC", + "add_bcc_entry": "Добавить правило BCC", "add_domain": "Добавить домен", "add_domain_alias": "Добавить псевдоним домена", "add_domain_record_first": "Пожалуйста, сначала добавьте домен", @@ -719,14 +719,14 @@ "allow_from_smtp_info": "Укажите IPv4/IPv6 адреса и/или подсети.
Оставьте поле пустым, чтобы разрешить отправку с любых адресов.", "allowed_protocols": "Разрешенные протоколы", "backup_mx": "Резервный MX", - "bcc": "Правила BBC", + "bcc": "Правила BCC", "bcc_destination": "Назначение BCC", "bcc_destinations": "Назначение BCC", "bcc_info": "Правила BCC используются для скрытой пересылки копий всех сообщений на другой адрес. Правило типа \"получатель\" используется, когда локальный получатель выступает в качестве получателя почты. Правило типа \"отправитель\" соответствуют тому же принципу. Локальный домен не будут проинформированы о неудачной доставке.", "bcc_local_dest": "Локальный домен", - "bcc_map": "Правила BBC", + "bcc_map": "Правила BCC", "bcc_map_type": "Тип BCC", - "bcc_maps": "Правила BBC", + "bcc_maps": "Правила BCC", "bcc_rcpt_map": "Получатель", "bcc_sender_map": "Отправитель", "bcc_to_rcpt": "Переключиться на тип \"получатель\"", diff --git a/data/web/lang/lang.uk-ua.json b/data/web/lang/lang.uk-ua.json index 73122464..5cc70445 100644 --- a/data/web/lang/lang.uk-ua.json +++ b/data/web/lang/lang.uk-ua.json @@ -391,7 +391,7 @@ "last_key": "Останній ключ не можна видалити, натомість вимкніть TFA.", "login_failed": "Введено неправильний логін або пароль", "mailbox_invalid": "Неприпустима адреса поштового акаунту", - "mailbox_quota_left_exceeded": "Недостатньо вільного місця (місця залишилося: %d МіБ)", + "mailbox_quota_left_exceeded": "Недостатньо вільного місця (залишилося: %d МіБ)", "malformed_username": "Некоректне ім'я користувача", "map_content_empty": "Зміст правила не може бути порожнім", "max_alias_exceeded": "Перевищено максимальну кількість псевдонімів", @@ -478,7 +478,8 @@ "extended_sender_acl_denied": "відсутній ACL для встановлення зовнішніх адрес відправників", "template_exists": "Шаблон %s вже існує", "template_id_invalid": "Ідентифікатор шаблону %s недійсний", - "template_name_invalid": "Ім'я шаблону невірне" + "template_name_invalid": "Ім'я шаблону невірне", + "img_size_exceeded": "Зображення перевищує максимальний розмір файлу" }, "debug": { "chart_this_server": "Діаграма (цей сервер)", @@ -626,7 +627,7 @@ "admin": "Редагувати адміністратора", "allow_from_smtp": "Дозволити SMTP тільки для цих IP", "allow_from_smtp_info": "Вкажіть IPv4/IPv6 адреси та/або підмережі.
Залиште поле порожнім, щоб дозволити відправлення з будь-яких адрес.", - "bcc_dest_format": "Призначенням правила BBC має бути єдина дійсна адреса електронної пошти.
Якщо вам потрібно надіслати копію на кілька адрес, створіть псевдонім і використовуйте його тут.", + "bcc_dest_format": "Призначенням правила BCC має бути єдина дійсна адреса електронної пошти.
Якщо вам потрібно надіслати копію на кілька адрес, створіть псевдонім і використовуйте його тут.", "comment_info": "Приватний коментар не видно користувачам, а публічний - відображається поряд із псевдонімом в особистому кабінеті користувача", "domain_quota": "Квота домену", "dont_check_sender_acl": "Вимкнути перевірку відправника для домену %s та псевдонімів домену", @@ -725,7 +726,7 @@ "add": "Додати", "add_alias": "Додати псевдонім", "add_alias_expand": "Копіювати псевдоніми на псевдоніми домену", - "add_bcc_entry": "Додати правило BBC", + "add_bcc_entry": "Додати правило BCC", "add_domain": "Додати домен", "add_domain_alias": "Додати псевдонім домену", "add_filter": "Додати фільтр", @@ -745,7 +746,7 @@ "bcc_local_dest": "Локальний домен", "bcc_map": "Правила ВВС", "bcc_map_type": "Тип BCC", - "bcc_maps": "Правила BBC", + "bcc_maps": "Правила BCC", "bcc_rcpt_map": "Одержувач", "bcc_sender_map": "Відправник", "bcc_to_rcpt": "Перейти на тип \"одержувач\"", From 8753ea2be61d886de220b7ceff77d98c179dc22c Mon Sep 17 00:00:00 2001 From: Dmitriy Alekseev <1865999+dragoangel@users.noreply.github.com> Date: Mon, 12 Aug 2024 10:05:08 +0200 Subject: [PATCH 119/138] [Rspamd] Fix bayes config (#6000) * [Rspamd] Fix bayes config Add hint about classifier name, and add missing learn_condition * Update statistic.conf --- data/conf/rspamd/local.d/statistic.conf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/data/conf/rspamd/local.d/statistic.conf b/data/conf/rspamd/local.d/statistic.conf index 1ca3e082..baa3f1c2 100644 --- a/data/conf/rspamd/local.d/statistic.conf +++ b/data/conf/rspamd/local.d/statistic.conf @@ -1,12 +1,14 @@ classifier "bayes" { + # name = "custom"; # 'name' parameter must be set if multiple classifiers are defined + learn_condition = 'return require("lua_bayes_learn").can_learn'; + new_schema = true; tokenizer { name = "osb"; } backend = "redis"; min_tokens = 11; min_learns = 5; - new_schema = true; - expire = 2592000; + expire = 7776000; statfile { symbol = "BAYES_HAM"; spam = false; From b1c1e403d2ff9993c07c5c62ba82744a69238564 Mon Sep 17 00:00:00 2001 From: Niklas Meyer Date: Tue, 13 Aug 2024 09:43:59 +0200 Subject: [PATCH 120/138] sogo: update to 5.11.0 + Rebase on Bookworm (#6002) * sogo: update to 5.11.0 * compose: bump sogo compose tag --- data/Dockerfiles/sogo/Dockerfile | 8 ++++---- data/Dockerfiles/sogo/syslog-ng-redis_slave.conf | 2 +- data/Dockerfiles/sogo/syslog-ng.conf | 2 +- docker-compose.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/data/Dockerfiles/sogo/Dockerfile b/data/Dockerfiles/sogo/Dockerfile index 6366c12f..2485b6a8 100644 --- a/data/Dockerfiles/sogo/Dockerfile +++ b/data/Dockerfiles/sogo/Dockerfile @@ -1,13 +1,13 @@ -FROM debian:bullseye-slim +FROM debian:bookworm-slim -LABEL maintainer = "The Infrastructure Company GmbH " +LABEL maintainer="The Infrastructure Company GmbH " ARG DEBIAN_FRONTEND=noninteractive -ARG DEBIAN_VERSION=bullseye +ARG DEBIAN_VERSION=bookworm ARG SOGO_DEBIAN_REPOSITORY=http://www.axis.cz/linux/debian # renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^(?.*)$ ARG GOSU_VERSION=1.17 -ENV LC_ALL C +ENV LC_ALL=C # Prerequisites RUN echo "Building from repository $SOGO_DEBIAN_REPOSITORY" \ diff --git a/data/Dockerfiles/sogo/syslog-ng-redis_slave.conf b/data/Dockerfiles/sogo/syslog-ng-redis_slave.conf index 9b460bd3..7abfc4b5 100644 --- a/data/Dockerfiles/sogo/syslog-ng-redis_slave.conf +++ b/data/Dockerfiles/sogo/syslog-ng-redis_slave.conf @@ -1,4 +1,4 @@ -@version: 3.28 +@version: 3.38 @include "scl.conf" options { chain_hostnames(off); diff --git a/data/Dockerfiles/sogo/syslog-ng.conf b/data/Dockerfiles/sogo/syslog-ng.conf index 889a3f32..f16a2920 100644 --- a/data/Dockerfiles/sogo/syslog-ng.conf +++ b/data/Dockerfiles/sogo/syslog-ng.conf @@ -1,4 +1,4 @@ -@version: 3.28 +@version: 3.38 @include "scl.conf" options { chain_hostnames(off); diff --git a/docker-compose.yml b/docker-compose.yml index 0f96aeac..1df07ea1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -176,7 +176,7 @@ services: - phpfpm sogo-mailcow: - image: mailcow/sogo:1.123 + image: mailcow/sogo:1.124 environment: - DBNAME=${DBNAME} - DBUSER=${DBUSER} From b26ccc2019921aa399d801a5241dbdf21b8350c0 Mon Sep 17 00:00:00 2001 From: Niklas Meyer Date: Tue, 13 Aug 2024 15:59:57 +0200 Subject: [PATCH 121/138] unbound: fix healthcheck logging + added fail tolerance to checks (#6004) * unbound: fix healthcheck logging to stdout + rewrote healthcheck logic * compose: bump unbound tag * unbound: fixed healthcheck logic --- data/Dockerfiles/unbound/Dockerfile | 15 ++- data/Dockerfiles/unbound/healthcheck.sh | 128 ++++++++++++-------- data/Dockerfiles/unbound/stop-supervisor.sh | 10 ++ data/Dockerfiles/unbound/supervisord.conf | 32 +++++ data/Dockerfiles/unbound/syslog-ng.conf | 21 ++++ docker-compose.yml | 2 +- 6 files changed, 152 insertions(+), 56 deletions(-) create mode 100755 data/Dockerfiles/unbound/stop-supervisor.sh create mode 100644 data/Dockerfiles/unbound/supervisord.conf create mode 100644 data/Dockerfiles/unbound/syslog-ng.conf diff --git a/data/Dockerfiles/unbound/Dockerfile b/data/Dockerfiles/unbound/Dockerfile index 958d24e5..fc7b1481 100644 --- a/data/Dockerfiles/unbound/Dockerfile +++ b/data/Dockerfiles/unbound/Dockerfile @@ -5,14 +5,17 @@ LABEL maintainer = "The Infrastructure Company GmbH " RUN apk add --update --no-cache \ curl \ bind-tools \ + coreutils \ unbound \ bash \ openssl \ drill \ tzdata \ + syslog-ng \ + supervisor \ && curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache \ && chown root:unbound /etc/unbound \ - && adduser unbound tty \ + && adduser unbound tty \ && chmod 775 /etc/unbound EXPOSE 53/udp 53/tcp @@ -21,9 +24,13 @@ COPY docker-entrypoint.sh /docker-entrypoint.sh # healthcheck (dig, ping) COPY healthcheck.sh /healthcheck.sh +COPY syslog-ng.conf /etc/syslog-ng/syslog-ng.conf +COPY supervisord.conf /etc/supervisor/supervisord.conf +COPY stop-supervisor.sh /usr/local/sbin/stop-supervisor.sh + RUN chmod +x /healthcheck.sh -HEALTHCHECK --interval=30s --timeout=30s CMD [ "/healthcheck.sh" ] +HEALTHCHECK --interval=30s --timeout=10s \ + CMD sh -c '[ -f /tmp/healthcheck_status ] && [ "$(cat /tmp/healthcheck_status)" -eq 0 ] || exit 1' ENTRYPOINT ["/docker-entrypoint.sh"] - -CMD ["/usr/sbin/unbound"] +CMD exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf diff --git a/data/Dockerfiles/unbound/healthcheck.sh b/data/Dockerfiles/unbound/healthcheck.sh index 3da98e24..7d918112 100644 --- a/data/Dockerfiles/unbound/healthcheck.sh +++ b/data/Dockerfiles/unbound/healthcheck.sh @@ -1,76 +1,102 @@ #!/bin/bash -# Skip Unbound (DNS Resolver) Healthchecks (NOT Recommended!) -if [[ "${SKIP_UNBOUND_HEALTHCHECK}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then - SKIP_UNBOUND_HEALTHCHECK=y -fi +STATUS_FILE="/tmp/healthcheck_status" +RUNS=0 -# Reset logfile -echo "$(date +"%Y-%m-%d %H:%M:%S"): Starting health check - logs can be found in /var/log/healthcheck.log" -echo "$(date +"%Y-%m-%d %H:%M:%S"): Starting health check" > /var/log/healthcheck.log - -# Declare log function for logfile inside container -function log_to_file() { - echo "$(date +"%Y-%m-%d %H:%M:%S"): $1" >> /var/log/healthcheck.log +# Declare log function for logfile to stdout +function log_to_stdout() { +echo "$(date +"%Y-%m-%d %H:%M:%S"): $1" } # General Ping function to check general pingability function check_ping() { - declare -a ipstoping=("1.1.1.1" "8.8.8.8" "9.9.9.9") +declare -a ipstoping=("1.1.1.1" "8.8.8.8" "9.9.9.9") +local fail_tolerance=1 +local failures=0 - for ip in "${ipstoping[@]}" ; do - ping -q -c 3 -w 5 "$ip" - if [ $? -ne 0 ]; then - log_to_file "Healthcheck: Couldn't ping $ip for 5 seconds... Gave up!" - log_to_file "Please check your internet connection or firewall rules to fix this error, because a simple ping test should always go through from the unbound container!" - return 1 - fi +for ip in "${ipstoping[@]}" ; do + success=false + for ((i=1; i<=3; i++)); do + ping -q -c 3 -w 5 "$ip" > /dev/null + if [ $? -eq 0 ]; then + success=true + break + else + log_to_stdout "Healthcheck: Failed to ping $ip on attempt $i. Trying again..." + fi done + + if [ "$success" = false ]; then + log_to_stdout "Healthcheck: Couldn't ping $ip after 3 attempts. Marking this IP as failed." + ((failures++)) + fi +done + +if [ $failures -gt $fail_tolerance ]; then + log_to_stdout "Healthcheck: Too many ping failures ($fail_tolerance failures allowed, you got $failures failures), marking Healthcheck as unhealthy..." + return 1 +fi + +return 0 - log_to_file "Healthcheck: Ping Checks WORKING properly!" - return 0 } # General DNS Resolve Check against Unbound Resolver himself function check_dns() { - declare -a domains=("mailcow.email" "github.com" "hub.docker.com") +declare -a domains=("fuzzy.mailcow.email" "github.com" "hub.docker.com") +local fail_tolerance=1 +local failures=0 - for domain in "${domains[@]}" ; do - for ((i=1; i<=3; i++)); do - dig +short +timeout=2 +tries=1 "$domain" @127.0.0.1 > /dev/null - if [ $? -ne 0 ]; then - log_to_file "Healthcheck: DNS Resolution Failed on $i attempt! Trying again..." - if [ $i -eq 3 ]; then - log_to_file "Healthcheck: DNS Resolution not possible after $i attempts... Gave up!" - log_to_file "Maybe check your outbound firewall, as it needs to resolve DNS over TCP AND UDP!" - return 1 - fi +for domain in "${domains[@]}" ; do + success=false + for ((i=1; i<=3; i++)); do + dig_output=$(dig +short +timeout=2 +tries=1 "$domain" @127.0.0.1 2>/dev/null) + dig_rc=$? + + if [ $dig_rc -ne 0 ] || [ -z "$dig_output" ]; then + log_to_stdout "Healthcheck: DNS Resolution Failed on attempt $i for $domain! Trying again..." + else + success=true + break fi - done done - - log_to_file "Healthcheck: DNS Resolver WORKING properly!" - return 0 + if [ "$success" = false ]; then + log_to_stdout "Healthcheck: DNS Resolution not possible after 3 attempts for $domain... Gave up!" + ((failures++)) + fi +done + +if [ $failures -gt $fail_tolerance ]; then + log_to_stdout "Healthcheck: Too many DNS failures ($fail_tolerance failures allowed, you got $failures failures), marking Healthcheck as unhealthy..." + return 1 +fi + +return 0 } -if [[ ${SKIP_UNBOUND_HEALTHCHECK} == "y" ]]; then - log_to_file "Healthcheck: ALL CHECKS WERE SKIPPED! Unbound is healthy!" - exit 0 -fi +while true; do -# run checks, if check is not returning 0 (return value if check is ok), healthcheck will exit with 1 (marked in docker as unhealthy) -check_ping + if [[ ${SKIP_UNBOUND_HEALTHCHECK} == "y" ]]; then + log_to_stdout "Healthcheck: ALL CHECKS WERE SKIPPED! Unbound is healthy!" + echo "0" > $STATUS_FILE + sleep 365d + fi -if [ $? -ne 0 ]; then - exit 1 -fi + # run checks, if check is not returning 0 (return value if check is ok), healthcheck will exit with 1 (marked in docker as unhealthy) + check_ping + PING_STATUS=$? -check_dns + check_dns + DNS_STATUS=$? -if [ $? -ne 0 ]; then - exit 1 -fi + if [ $PING_STATUS -ne 0 ] || [ $DNS_STATUS -ne 0 ]; then + echo "1" > $STATUS_FILE -log_to_file "Healthcheck: ALL CHECKS WERE SUCCESSFUL! Unbound is healthy!" -exit 0 \ No newline at end of file + else + echo "0" > $STATUS_FILE + fi + + sleep 30 + +done \ No newline at end of file diff --git a/data/Dockerfiles/unbound/stop-supervisor.sh b/data/Dockerfiles/unbound/stop-supervisor.sh new file mode 100755 index 00000000..acd40273 --- /dev/null +++ b/data/Dockerfiles/unbound/stop-supervisor.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +printf "READY\n"; + +while read line; do + echo "Processing Event: $line" >&2; + kill -3 $(cat "/var/run/supervisord.pid") +done < /dev/stdin + +rm -rf /tmp/healthcheck_status \ No newline at end of file diff --git a/data/Dockerfiles/unbound/supervisord.conf b/data/Dockerfiles/unbound/supervisord.conf new file mode 100644 index 00000000..b47c8b11 --- /dev/null +++ b/data/Dockerfiles/unbound/supervisord.conf @@ -0,0 +1,32 @@ +[supervisord] +nodaemon=true +user=root +pidfile=/var/run/supervisord.pid + +[program:syslog-ng] +command=/usr/sbin/syslog-ng --foreground --no-caps +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +autostart=true + +[program:unbound] +command=/usr/sbin/unbound +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +autorestart=true + +[program:unbound-healthcheck] +command=/bin/bash /healthcheck.sh +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +autorestart=true + +[eventlistener:processes] +command=/usr/local/sbin/stop-supervisor.sh +events=PROCESS_STATE_STOPPED, PROCESS_STATE_EXITED, PROCESS_STATE_FATAL diff --git a/data/Dockerfiles/unbound/syslog-ng.conf b/data/Dockerfiles/unbound/syslog-ng.conf new file mode 100644 index 00000000..de858f9e --- /dev/null +++ b/data/Dockerfiles/unbound/syslog-ng.conf @@ -0,0 +1,21 @@ +@version: 4.5 +@include "scl.conf" +options { + chain_hostnames(off); + flush_lines(0); + use_dns(no); + use_fqdn(no); + owner("root"); group("adm"); perm(0640); + stats(freq(0)); + keep_timestamp(no); + bad_hostname("^gconfd$"); +}; +source s_dgram { + unix-dgram("/dev/log"); + internal(); +}; +destination d_stdout { pipe("/dev/stdout"); }; +log { + source(s_dgram); + destination(d_stdout); +}; diff --git a/docker-compose.yml b/docker-compose.yml index 1df07ea1..59f41785 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ services: unbound-mailcow: - image: mailcow/unbound:1.22 + image: mailcow/unbound:1.23 environment: - TZ=${TZ} - SKIP_UNBOUND_HEALTHCHECK=${SKIP_UNBOUND_HEALTHCHECK:-n} From a6f71faf46d5f30c762c35f5f6d16fac293a53e5 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Tue, 13 Aug 2024 16:07:09 +0200 Subject: [PATCH 122/138] github-actions: compacted auto nightly pr --- .github/ISSUE_TEMPLATE/pr_to_nighty_template.yml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/pr_to_nighty_template.yml b/.github/ISSUE_TEMPLATE/pr_to_nighty_template.yml index 8854ac9d..d9f87858 100644 --- a/.github/ISSUE_TEMPLATE/pr_to_nighty_template.yml +++ b/.github/ISSUE_TEMPLATE/pr_to_nighty_template.yml @@ -1,13 +1,3 @@ -## :memo: Brief description - - - - -## :computer: Commits - - - - ## :file_folder: Modified files - + \ No newline at end of file From e34afd3fdddabb82f4d71bf7e1e554d13ff21497 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Wed, 14 Aug 2024 10:02:59 +0200 Subject: [PATCH 123/138] flatcurve-fts: limit tokenizers for email adresses --- data/Dockerfiles/dovecot/docker-entrypoint.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/data/Dockerfiles/dovecot/docker-entrypoint.sh b/data/Dockerfiles/dovecot/docker-entrypoint.sh index bd1a44f3..c7564cad 100755 --- a/data/Dockerfiles/dovecot/docker-entrypoint.sh +++ b/data/Dockerfiles/dovecot/docker-entrypoint.sh @@ -257,10 +257,14 @@ plugin { fts_autoindex_exclude2 = \Trash fts = flatcurve + # Maximum term length can be set via the 'maxlen' argument (maxlen is + # specified in bytes, not number of UTF-8 characters) + fts_tokenizer_email_address = maxlen=100 + fts_tokenizer_generic = algorithm=simple maxlen=30 + # These are not flatcurve settings, but required for Dovecot FTS. See # Dovecot FTS Configuration link above for further information. fts_languages = en es de - fts_tokenizer_generic = algorithm=simple fts_tokenizers = generic email-address # OPTIONAL: Recommended default FTS core configuration From 1994f706c09f7a6d0ff0c8a858e2fa0db9af17dd Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Wed, 14 Aug 2024 10:03:42 +0200 Subject: [PATCH 124/138] dovecot: optimized dockerfile syntax --- data/Dockerfiles/dovecot/Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/Dockerfiles/dovecot/Dockerfile b/data/Dockerfiles/dovecot/Dockerfile index a832bff6..4b004cdf 100644 --- a/data/Dockerfiles/dovecot/Dockerfile +++ b/data/Dockerfiles/dovecot/Dockerfile @@ -1,12 +1,12 @@ FROM alpine:3.20 -LABEL maintainer = "The Infrastructure Company GmbH " +LABEL maintainer="The Infrastructure Company GmbH " # renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^(?.*)$ ARG GOSU_VERSION=1.16 -ENV LANG C.UTF-8 -ENV LC_ALL C.UTF-8 +ENV LANG=C.UTF-8 +ENV LC_ALL=C.UTF-8 # Add groups and users before installing Dovecot to not break compatibility RUN addgroup -g 5000 vmail \ @@ -133,4 +133,4 @@ COPY repl_health.sh /usr/local/bin/repl_health.sh COPY optimize-fts.sh /usr/local/bin/optimize-fts.sh ENTRYPOINT ["/docker-entrypoint.sh"] -CMD exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"] From 6c97c4f372b35bc9237a0d9f9b5696ff24cf0797 Mon Sep 17 00:00:00 2001 From: Niklas Meyer Date: Thu, 15 Aug 2024 09:50:36 +0200 Subject: [PATCH 125/138] Revert "Don't expose SMTP/IMAP if announced "not provided" via SRV" --- data/web/autoconfig.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/data/web/autoconfig.php b/data/web/autoconfig.php index 75046341..95952df0 100644 --- a/data/web/autoconfig.php +++ b/data/web/autoconfig.php @@ -39,9 +39,6 @@ header('Content-Type: application/xml'); %EMAILADDRESS% password-cleartext - @@ -49,7 +46,6 @@ if (count($records) == 0 || $records[0]['target'] != '') { ?> %EMAILADDRESS% password-cleartext - %EMAILADDRESS% password-cleartext - @@ -91,7 +84,6 @@ if (count($records) == 0 || $records[0]['target'] != '') { ?> %EMAILADDRESS% password-cleartext - If you didn't change the password given to you by the administrator or if you didn't change it in a long time, please consider doing that now. From c5e399ebc2c15f5ff2eb570894ffe37ef82bda27 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 15 Aug 2024 11:09:37 +0200 Subject: [PATCH 126/138] .github: Add pull_request_template.md --- .github/PULL_REQUEST_TEMPLATE.md | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..68ead39f --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,38 @@ + + +## Contribution Guidelines + +* [ ] I've read the [contribution guidelines](https://github.com/mailcow/mailcow-dockerized/blob/master/CONTRIBUTING.md) and wholeheartedly agree them + + + +## What does this PR include? + +### Short Description + + + +### Affected Containers + + + + + +## Did you run tests? + +### What did you tested? + + + +### What were the final results? (Awaited, got) + + \ No newline at end of file From e00d0d5f8de369fd8499aae78825aa4a670449e3 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 15 Aug 2024 11:32:28 +0200 Subject: [PATCH 127/138] Updated contributing.md --- CONTRIBUTING.md | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 623d2cab..fae8f1d5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,25 +1,42 @@ -# Contribution Guidelines (Last modified on 27th June 2024) +# Contribution Guidelines +**_Last modified on 15th August 2024_** First of all, thank you for wanting to provide a bugfix or a new feature for the mailcow community, it's because of your help that the project can continue to grow! -## Pull Requests (Last modified on 27th June 2024) +As we want to keep mailcow's development structured we setup these Guidelines which helps you to create your issue/pull request accordingly. + +**PLEASE NOTE, THAT WE MIGHT CLOSE ISSUES/PULL REQUESTS IF THEY DON'T FULLFIL OUR WRITTEN GUIDELINES WRITTEN INSIDE THIS DOCUMENT**. So please check this guidelines before you propose a Issue/Pull Request. + +## Topics + +- [Pull Requests](#pull-requests) +- [Issue Reporting](#issue-reporting) + - [Guidelines](#issue-reporting-guidelines) + - [Issue Report Guide](#issue-report-guide) + +## Pull Requests +**_Last modified on 15th August 2024_** However, please note the following regarding pull requests: 1. **ALWAYS** create your PR using the staging branch of your locally cloned mailcow instance, as the pull request will end up in said staging branch of mailcow once approved. Ideally, you should simply create a new branch for your pull request that is named after the type of your PR (e.g. `feat/` for function updates or `fix/` for bug fixes) and the actual content (e.g. `sogo-6.0.0` for an update from SOGo to version 6 or `html-escape` for a fix that includes escaping HTML in mailcow). 2. **ALWAYS** report/request issues/features in the english language, even though mailcow is a german based company. This is done to allow other GitHub users to reply to your issues/requests too which did not speak german or other languages besides english. -3. Please **keep** this pull request branch **clean** and free of commits that have nothing to do with the changes you have made (e.g. commits from other users from other branches). *If you make changes to the `update.sh` script or other scripts that trigger a commit, there is usually a developer mode for clean working in this case. +3. Please **keep** this pull request branch **clean** and free of commits that have nothing to do with the changes you have made (e.g. commits from other users from other branches). *If you make changes to the `update.sh` script or other scripts that trigger a commit, there is usually a developer mode for clean working in this case.* 4. **Test your changes before you commit them as a pull request.** If possible, write a small **test log** or demonstrate the functionality with a **screenshot or GIF**. *We will of course also test your pull request ourselves, but proof from you will save us the question of whether you have tested your own changes yourself.* -5. Please **ALWAYS** create the actual pull request against the staging branch and **NEVER** directly against the master branch. *If you forget to do this, our moobot will remind you to switch the branch to staging.* -6. Wait for a merge commit: It may happen that we do not accept your pull request immediately or sometimes not at all for various reasons. Please do not be disappointed if this is the case. We always endeavor to incorporate any meaningful changes from the community into the mailcow project. -7. If you are planning larger and therefore more complex pull requests, it would be advisable to first announce this in a separate issue and then start implementing it after the idea has been accepted in order to avoid unnecessary frustration and effort! +5. **Please use** the pull request template we provide once creating a pull request. *HINT: During editing you encounter comments which looks like: ``. These can be removed or kept, as they will not rendered later on GitHub! Please only create actual content without the said comments.* +6. Please **ALWAYS** create the actual pull request against the staging branch and **NEVER** directly against the master branch. *If you forget to do this, our moobot will remind you to switch the branch to staging.* +7. Wait for a merge commit: It may happen that we do not accept your pull request immediately or sometimes not at all for various reasons. Please do not be disappointed if this is the case. We always endeavor to incorporate any meaningful changes from the community into the mailcow project. +8. If you are planning larger and therefore more complex pull requests, it would be advisable to first announce this in a separate issue and then start implementing it after the idea has been accepted in order to avoid unnecessary frustration and effort! --- -## Issue Reporting (Last modified on 27th June 2024) +## Issue Reporting +**_Last modified on 15th August 2024_** If you plan to report a issue within mailcow please read and understand the following rules: +### Issue Reporting Guidelines + 1. **ONLY** use the issue tracker for bug reports or improvement requests and NOT for support questions. For support questions you can either contact the [mailcow community on Telegram](https://docs.mailcow.email/#community-support-and-chat) or the mailcow team directly in exchange for a [support fee](https://docs.mailcow.email/#commercial-support). 2. **ONLY** report an error if you have the **necessary know-how (at least the basics)** for the administration of an e-mail server and the usage of Docker. mailcow is a complex and fully-fledged e-mail server including groupware components on a Docker basement and it requires a bit of technical know-how for debugging and operating. 3. **ALWAYS** report/request issues/features in the english language, even though mailcow is a german based company. This is done to allow other GitHub users to reply to your issues/requests too which did not speak german or other languages besides english. @@ -29,7 +46,7 @@ If you plan to report a issue within mailcow please read and understand the foll 7. When you create a issue/feature request: Please note that the creation does **not guarantee an instant implementation or fix by the mailcow team or the community**. 8. Please **ALWAYS** anonymize any sensitive information in your bug report or feature request before submitting it. -### Quick guide to reporting problems: +### Issue Report Guide 1. Read your logs; follow them to see what the reason for your problem is. 2. Follow the leads given to you in your logfiles and start investigating. 3. Restarting the troubled service or the whole stack to see if the problem persists. From eb3f88fc91b38688baa91529c3d39fe2e486c3e1 Mon Sep 17 00:00:00 2001 From: Janek <6506725+jkrgr0@users.noreply.github.com> Date: Fri, 16 Aug 2024 08:47:03 +0200 Subject: [PATCH 128/138] =?UTF-8?q?fix:=20=F0=9F=9A=91=20Fixed=20version?= =?UTF-8?q?=20parsing=20of=20docker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only the first result (the major version) is relevant Closes #6015 --- update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update.sh b/update.sh index b89514e5..9b7fd265 100755 --- a/update.sh +++ b/update.sh @@ -329,7 +329,7 @@ for bin in curl docker git awk sha1sum grep cut; do done # Check Docker Version (need at least 24.X) -docker_version=$(docker -v | grep -oP '\d+\.\d+\.\d+' | cut -d '.' -f 1) +docker_version=$(docker -v | grep -oP '\d+\.\d+\.\d+' | cut -d '.' -f 1 | head -1) if [[ $docker_version -lt 24 ]]; then echo -e "\e[31mCannot find Docker with a Version higher or equals 24.0.0\e[0m" From f3da8bb85ff98164f45c742aff957c960b75c69e Mon Sep 17 00:00:00 2001 From: Hassan A Hashim Date: Mon, 19 Aug 2024 11:42:11 +0300 Subject: [PATCH 129/138] Refactor/Change Dockerfiles cmd from shell to exec form (#6019) * Update `dockerapi/Dockerfile` CMD from shell to exec format * Update `postfix/Dockerfile` CMD from shell to exec format * Update `sogo/Dockerfile` CMD from shell to exec format * Update `unbound/Dockerfile` CMD from shell to exec format * Update `watchdog/Dockerfile` CMD from shell to exec format --- data/Dockerfiles/dockerapi/Dockerfile | 2 +- data/Dockerfiles/postfix/Dockerfile | 2 +- data/Dockerfiles/sogo/Dockerfile | 2 +- data/Dockerfiles/unbound/Dockerfile | 2 +- data/Dockerfiles/watchdog/Dockerfile | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/data/Dockerfiles/dockerapi/Dockerfile b/data/Dockerfiles/dockerapi/Dockerfile index 92c19dcc..bbd4542e 100644 --- a/data/Dockerfiles/dockerapi/Dockerfile +++ b/data/Dockerfiles/dockerapi/Dockerfile @@ -24,4 +24,4 @@ COPY main.py /app/main.py COPY modules/ /app/modules/ ENTRYPOINT ["/bin/sh", "/app/docker-entrypoint.sh"] -CMD exec python main.py \ No newline at end of file +CMD ["python", "main.py"] \ No newline at end of file diff --git a/data/Dockerfiles/postfix/Dockerfile b/data/Dockerfiles/postfix/Dockerfile index 0f1911c6..5449360b 100644 --- a/data/Dockerfiles/postfix/Dockerfile +++ b/data/Dockerfiles/postfix/Dockerfile @@ -60,4 +60,4 @@ EXPOSE 588 ENTRYPOINT ["/docker-entrypoint.sh"] -CMD exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"] diff --git a/data/Dockerfiles/sogo/Dockerfile b/data/Dockerfiles/sogo/Dockerfile index 2485b6a8..7b8b1c71 100644 --- a/data/Dockerfiles/sogo/Dockerfile +++ b/data/Dockerfiles/sogo/Dockerfile @@ -55,4 +55,4 @@ RUN chmod +x /bootstrap-sogo.sh \ ENTRYPOINT ["/docker-entrypoint.sh"] -CMD exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf \ No newline at end of file +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"] \ No newline at end of file diff --git a/data/Dockerfiles/unbound/Dockerfile b/data/Dockerfiles/unbound/Dockerfile index fc7b1481..7e4f18de 100644 --- a/data/Dockerfiles/unbound/Dockerfile +++ b/data/Dockerfiles/unbound/Dockerfile @@ -33,4 +33,4 @@ HEALTHCHECK --interval=30s --timeout=10s \ CMD sh -c '[ -f /tmp/healthcheck_status ] && [ "$(cat /tmp/healthcheck_status)" -eq 0 ] || exit 1' ENTRYPOINT ["/docker-entrypoint.sh"] -CMD exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"] diff --git a/data/Dockerfiles/watchdog/Dockerfile b/data/Dockerfiles/watchdog/Dockerfile index 0f3e7dfb..f8aa262b 100644 --- a/data/Dockerfiles/watchdog/Dockerfile +++ b/data/Dockerfiles/watchdog/Dockerfile @@ -37,4 +37,4 @@ RUN apk add --update \ COPY watchdog.sh /watchdog.sh COPY check_mysql_slavestatus.sh /usr/lib/nagios/plugins/check_mysql_slavestatus.sh -CMD /watchdog.sh +CMD ["/watchdog.sh"] From cb50d08605875e4f1862d6309e3ff9145423c9ad Mon Sep 17 00:00:00 2001 From: Niklas Meyer Date: Mon, 19 Aug 2024 11:08:13 +0200 Subject: [PATCH 130/138] dovecot: added timeout option when sa-rules cannot be downloaded (#6025) * dovecot: added timeout option when sa-rules cannot be downloaded * dovecot: changed sa-rules exit code to 0 to allow dovecot to start afterwards --- data/Dockerfiles/dovecot/sa-rules.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/data/Dockerfiles/dovecot/sa-rules.sh b/data/Dockerfiles/dovecot/sa-rules.sh index 107ea717..2a513805 100755 --- a/data/Dockerfiles/dovecot/sa-rules.sh +++ b/data/Dockerfiles/dovecot/sa-rules.sh @@ -11,10 +11,14 @@ else fi # Deploy -curl --connect-timeout 15 --retry 10 --max-time 30 https://www.spamassassin.heinlein-support.de/$(dig txt 1.4.3.spamassassin.heinlein-support.de +short | tr -d '"' | tr -dc '0-9').tar.gz --output /tmp/sa-rules-heinlein.tar.gz -if gzip -t /tmp/sa-rules-heinlein.tar.gz; then - tar xfvz /tmp/sa-rules-heinlein.tar.gz -C /tmp/sa-rules-heinlein - cat /tmp/sa-rules-heinlein/*cf > /etc/rspamd/custom/sa-rules +if curl --connect-timeout 15 --retry 10 --max-time 30 https://www.spamassassin.heinlein-support.de/$(dig txt 1.4.3.spamassassin.heinlein-support.de +short | tr -d '"' | tr -dc '0-9').tar.gz --output /tmp/sa-rules-heinlein.tar.gz; then + if gzip -t /tmp/sa-rules-heinlein.tar.gz; then + tar xfvz /tmp/sa-rules-heinlein.tar.gz -C /tmp/sa-rules-heinlein + cat /tmp/sa-rules-heinlein/*cf > /etc/rspamd/custom/sa-rules + fi +else + echo "Failed to download SA rules. Exiting." + exit 0 # Must be 0 otherwise dovecot would not start at all fi sed -i -e 's/\([^\\]\)\$\([^\/]\)/\1\\$\2/g' /etc/rspamd/custom/sa-rules From b70bcd36fbe84136285ccbce92fa7839f830e350 Mon Sep 17 00:00:00 2001 From: Niklas Meyer Date: Mon, 19 Aug 2024 11:33:28 +0200 Subject: [PATCH 131/138] containers: use mariadb-admin instead of deprecated mysqladmin (#6026) * dockerfiles: use mariadb-admin instead of deprecated mysqladmin command * compose: bump compose tags --- data/Dockerfiles/acme/acme.sh | 2 +- data/Dockerfiles/dovecot/docker-entrypoint.sh | 2 +- data/Dockerfiles/phpfpm/docker-entrypoint.sh | 4 ++-- data/Dockerfiles/postfix/postfix.sh | 2 +- data/Dockerfiles/sogo/bootstrap-sogo.sh | 2 +- data/Dockerfiles/watchdog/watchdog.sh | 2 +- docker-compose.yml | 12 ++++++------ 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/data/Dockerfiles/acme/acme.sh b/data/Dockerfiles/acme/acme.sh index 9682684e..3c7658d8 100755 --- a/data/Dockerfiles/acme/acme.sh +++ b/data/Dockerfiles/acme/acme.sh @@ -117,7 +117,7 @@ fi chmod 600 ${ACME_BASE}/key.pem log_f "Waiting for database..." -while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent > /dev/null; do +while ! /usr/bin/mariadb-admin status --ssl=false --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent > /dev/null; do sleep 2 done log_f "Database OK" diff --git a/data/Dockerfiles/dovecot/docker-entrypoint.sh b/data/Dockerfiles/dovecot/docker-entrypoint.sh index c7564cad..2f0bfadf 100755 --- a/data/Dockerfiles/dovecot/docker-entrypoint.sh +++ b/data/Dockerfiles/dovecot/docker-entrypoint.sh @@ -2,7 +2,7 @@ set -e # Wait for MySQL to warm-up -while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do +while ! mariadb-admin status --ssl=false --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do echo "Waiting for database to come up..." sleep 2 done diff --git a/data/Dockerfiles/phpfpm/docker-entrypoint.sh b/data/Dockerfiles/phpfpm/docker-entrypoint.sh index 87b4e298..798a2585 100755 --- a/data/Dockerfiles/phpfpm/docker-entrypoint.sh +++ b/data/Dockerfiles/phpfpm/docker-entrypoint.sh @@ -3,7 +3,7 @@ function array_by_comma { local IFS=","; echo "$*"; } # Wait for containers -while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do +while ! mariadb-admin status --ssl=false --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do echo "Waiting for SQL..." sleep 2 done @@ -44,7 +44,7 @@ until [[ ${SQL_UPGRADE_STATUS} == 'success' ]]; do echo "MySQL applied an upgrade, debug output:" echo ${SQL_FULL_UPGRADE_RETURN} sleep 3 - while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do + while ! mariadb-admin status --ssl=false --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do echo "Waiting for SQL to return, please wait" sleep 2 done diff --git a/data/Dockerfiles/postfix/postfix.sh b/data/Dockerfiles/postfix/postfix.sh index a173e9a7..8ffb76f6 100755 --- a/data/Dockerfiles/postfix/postfix.sh +++ b/data/Dockerfiles/postfix/postfix.sh @@ -5,7 +5,7 @@ trap "postfix stop" EXIT [[ ! -d /opt/postfix/conf/sql/ ]] && mkdir -p /opt/postfix/conf/sql/ # Wait for MySQL to warm-up -while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do +while ! mariadb-admin status --ssl=false --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do echo "Waiting for database to come up..." sleep 2 done diff --git a/data/Dockerfiles/sogo/bootstrap-sogo.sh b/data/Dockerfiles/sogo/bootstrap-sogo.sh index bae06054..51880ea6 100755 --- a/data/Dockerfiles/sogo/bootstrap-sogo.sh +++ b/data/Dockerfiles/sogo/bootstrap-sogo.sh @@ -1,7 +1,7 @@ #!/bin/bash # Wait for MySQL to warm-up -while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do +while ! mariadb-admin status --ssl=false --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do echo "Waiting for database to come up..." sleep 2 done diff --git a/data/Dockerfiles/watchdog/watchdog.sh b/data/Dockerfiles/watchdog/watchdog.sh index 7f125f76..81d65d90 100755 --- a/data/Dockerfiles/watchdog/watchdog.sh +++ b/data/Dockerfiles/watchdog/watchdog.sh @@ -33,7 +33,7 @@ if [[ ! -p /tmp/com_pipe ]]; then fi # Wait for containers -while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do +while ! mariadb-admin status --ssl=false --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do echo "Waiting for SQL..." sleep 2 done diff --git a/docker-compose.yml b/docker-compose.yml index 59f41785..cf0a028f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -111,7 +111,7 @@ services: - rspamd php-fpm-mailcow: - image: mailcow/phpfpm:1.88 + image: mailcow/phpfpm:1.89 command: "php-fpm -d date.timezone=${TZ} -d expose_php=0" depends_on: - redis-mailcow @@ -176,7 +176,7 @@ services: - phpfpm sogo-mailcow: - image: mailcow/sogo:1.124 + image: mailcow/sogo:1.125 environment: - DBNAME=${DBNAME} - DBUSER=${DBUSER} @@ -223,7 +223,7 @@ services: - sogo dovecot-mailcow: - image: mailcow/dovecot:2.0 + image: mailcow/dovecot:2.1 depends_on: - mysql-mailcow - netfilter-mailcow @@ -307,7 +307,7 @@ services: - dovecot postfix-mailcow: - image: mailcow/postfix:1.75 + image: mailcow/postfix:1.76 depends_on: mysql-mailcow: condition: service_started @@ -407,7 +407,7 @@ services: condition: service_started unbound-mailcow: condition: service_healthy - image: mailcow/acme:1.89 + image: mailcow/acme:1.90 dns: - ${IPV4_NETWORK:-172.22.1}.254 environment: @@ -463,7 +463,7 @@ services: - /lib/modules:/lib/modules:ro watchdog-mailcow: - image: mailcow/watchdog:2.04 + image: mailcow/watchdog:2.05 dns: - ${IPV4_NETWORK:-172.22.1}.254 tmpfs: From 3d628696643d5b1a1dd68bcbc5ff3051c0d1b0c6 Mon Sep 17 00:00:00 2001 From: Hassan A Hashim Date: Mon, 19 Aug 2024 16:47:55 +0300 Subject: [PATCH 132/138] Fix: bash variables are not quoted (#6022) * Fix: Double quote variables to prevent word splitting * Fix `update.sh`: Double quote to prevent word splitting * Refactor: Remove unnecessary white-spaces. --- generate_config.sh | 10 +- update.sh | 290 ++++++++++++++++++++++----------------------- 2 files changed, 150 insertions(+), 150 deletions(-) diff --git a/generate_config.sh b/generate_config.sh index cc5ba1ce..4d8fcd26 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -9,7 +9,7 @@ if [[ "$(uname -r)" =~ ^4\.15\.0-60 ]]; then fi if [[ "$(uname -r)" =~ ^4\.4\. ]]; then - if grep -q Ubuntu <<< $(uname -a); then + if grep -q Ubuntu <<< "$(uname -a)"; then echo "DO NOT RUN mailcow ON THIS UBUNTU KERNEL!"; echo "Please update to linux-generic-hwe-16.04 by running \"apt-get install --install-recommends linux-generic-hwe-16.04\"" exit 1 @@ -158,7 +158,7 @@ done MEM_TOTAL=$(awk '/MemTotal/ {print $2}' /proc/meminfo) if [ -z "${SKIP_CLAMD}" ]; then - if [ ${MEM_TOTAL} -le "2621440" ]; then + if [ "${MEM_TOTAL}" -le "2621440" ]; then echo "Installed memory is <= 2.5 GiB. It is recommended to disable ClamAV to prevent out-of-memory situations." echo "ClamAV can be re-enabled by setting SKIP_CLAMD=n in mailcow.conf." read -r -p "Do you want to disable ClamAV now? [Y/n] " response @@ -176,10 +176,10 @@ if [ -z "${SKIP_CLAMD}" ]; then fi if [ -z "${SKIP_SOLR}" ]; then - if [ ${MEM_TOTAL} -le "2097152" ]; then + if [ "${MEM_TOTAL}" -le "2097152" ]; then echo "Disabling Solr on low-memory system." SKIP_SOLR=y - elif [ ${MEM_TOTAL} -le "3670016" ]; then + elif [ "${MEM_TOTAL}" -le "3670016" ]; then echo "Installed memory is <= 3.5 GiB. It is recommended to disable Solr to prevent out-of-memory situations." echo "Solr is a prone to run OOM and should be monitored. The default Solr heap size is 1024 MiB and should be set in mailcow.conf according to your expected load." echo "Solr can be re-enabled by setting SKIP_SOLR=n in mailcow.conf but will refuse to start with less than 2 GB total memory." @@ -218,7 +218,7 @@ if [[ ${SKIP_BRANCH} != y ]]; then done git fetch --all - git checkout -f $MAILCOW_BRANCH + git checkout -f "$MAILCOW_BRANCH" elif [[ ${SKIP_BRANCH} == y ]]; then echo -e "\033[33mEnabled Dev Mode.\033[0m" diff --git a/update.sh b/update.sh index 9b7fd265..6195c4fe 100755 --- a/update.sh +++ b/update.sh @@ -22,13 +22,13 @@ prefetch_images() { fi fi RET_C=0 - until docker pull ${image}; do + until docker pull "${image}"; do RET_C=$((RET_C + 1)) echo -e "\e[33m\nError pulling $image, retrying...\e[0m" [ ${RET_C} -gt 3 ] && { echo -e "\e[31m\nToo many failed retries, exiting\e[0m"; exit 1; } sleep 1 done - done < <(git show origin/${BRANCH}:docker-compose.yml | grep "image:" | awk '{ gsub("image:","", $3); print $2 }') + done < <(git show "origin/${BRANCH}:docker-compose.yml" | grep "image:" | awk '{ gsub("image:","", $3); print $2 }') } docker_garbage() { @@ -39,9 +39,9 @@ docker_garbage() { COMPOSE_IMAGES=($(grep -oP "image: \Kmailcow.+" "${SCRIPT_DIR}/docker-compose.yml")) for existing_image in $(docker images --format "{{.ID}}:{{.Repository}}:{{.Tag}}" | grep 'mailcow/'); do - ID=$(echo $existing_image | cut -d ':' -f 1) - REPOSITORY=$(echo $existing_image | cut -d ':' -f 2) - TAG=$(echo $existing_image | cut -d ':' -f 3) + ID=$(echo "$existing_image" | cut -d ':' -f 1) + REPOSITORY=$(echo "$existing_image" | cut -d ':' -f 2) + TAG=$(echo "$existing_image" | cut -d ':' -f 3) if [[ " ${COMPOSE_IMAGES[@]} " =~ " ${REPOSITORY}:${TAG} " ]]; then continue @@ -109,12 +109,12 @@ migrate_docker_nat() { echo -e "\e[33mWarning:\e[0m You seem to have modified the /etc/docker/daemon.json configuration by yourself and not fully/correctly activated the native IPv6 NAT implementation." echo "You will need to merge your existing configuration manually or fix/delete the existing daemon.json configuration before trying the update process again." echo -e "Please merge the following content and restart the Docker daemon:\n" - echo ${NAT_CONFIG} + echo "${NAT_CONFIG}" return 1 fi else echo "Working on IPv6 NAT, please wait..." - echo ${NAT_CONFIG} > /etc/docker/daemon.json + echo "${NAT_CONFIG}" > /etc/docker/daemon.json ip6tables -F -t nat [[ -e /etc/rc.conf ]] && rc-service docker restart || systemctl restart docker.service if [[ $? -ne 0 ]]; then @@ -165,7 +165,7 @@ remove_obsolete_nginx_ports() { fi fi fi - done + done } detect_docker_compose_command(){ @@ -176,11 +176,11 @@ if ! [[ "${DOCKER_COMPOSE_VERSION}" =~ ^(native|standalone)$ ]]; then COMPOSE_COMMAND="docker compose" echo -e "\e[33mFound Docker Compose Plugin (native).\e[0m" echo -e "\e[33mSetting the DOCKER_COMPOSE_VERSION Variable to native\e[0m" - sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=native/' $SCRIPT_DIR/mailcow.conf + sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=native/' "$SCRIPT_DIR/mailcow.conf" sleep 2 echo -e "\e[33mNotice: You'll have to update this Compose Version via your Package Manager manually!\e[0m" else - echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m" + echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m" echo -e "\e[31mPlease update/install it manually regarding to this doc site: https://docs.mailcow.email/install/\e[0m" exit 1 fi @@ -191,58 +191,58 @@ if ! [[ "${DOCKER_COMPOSE_VERSION}" =~ ^(native|standalone)$ ]]; then COMPOSE_COMMAND="docker-compose" echo -e "\e[33mFound Docker Compose Standalone.\e[0m" echo -e "\e[33mSetting the DOCKER_COMPOSE_VERSION Variable to standalone\e[0m" - sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=standalone/' $SCRIPT_DIR/mailcow.conf + sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=standalone/' "$SCRIPT_DIR/mailcow.conf" sleep 2 echo -e "\e[33mNotice: For an automatic update of docker-compose please use the update_compose.sh scripts located at the helper-scripts folder.\e[0m" else - echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m" + echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m" echo -e "\e[31mPlease update/install regarding to this doc site: https://docs.mailcow.email/install/\e[0m" exit 1 fi fi else - echo -e "\e[31mCannot find Docker Compose.\e[0m" + echo -e "\e[31mCannot find Docker Compose.\e[0m" echo -e "\e[31mPlease install it regarding to this doc site: https://docs.mailcow.email/install/\e[0m" exit 1 fi elif [ "${DOCKER_COMPOSE_VERSION}" == "native" ]; then COMPOSE_COMMAND="docker compose" - # Check if Native Compose works and has not been deleted + # Check if Native Compose works and has not been deleted if ! $COMPOSE_COMMAND > /dev/null 2>&1; then # IF it not exists/work anymore try the other command COMPOSE_COMMAND="docker-compose" if ! $COMPOSE_COMMAND > /dev/null 2>&1 || ! $COMPOSE_COMMAND --version | grep "^2." > /dev/null 2>&1; then # IF it cannot find Standalone in > 2.X, then script stops - echo -e "\e[31mCannot find Docker Compose or the Version is lower then 2.X.X.\e[0m" + echo -e "\e[31mCannot find Docker Compose or the Version is lower then 2.X.X.\e[0m" echo -e "\e[31mPlease install it regarding to this doc site: https://docs.mailcow.email/install/\e[0m" exit 1 fi # If it finds the standalone Plugin it will use this instead and change the mailcow.conf Variable accordingly echo -e "\e[31mFound different Docker Compose Version then declared in mailcow.conf!\e[0m" echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable from native to standalone\e[0m" - sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=standalone/' $SCRIPT_DIR/mailcow.conf + sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=standalone/' "$SCRIPT_DIR/mailcow.conf" sleep 2 fi elif [ "${DOCKER_COMPOSE_VERSION}" == "standalone" ]; then COMPOSE_COMMAND="docker-compose" - # Check if Standalone Compose works and has not been deleted + # Check if Standalone Compose works and has not been deleted if ! $COMPOSE_COMMAND > /dev/null 2>&1 && ! $COMPOSE_COMMAND --version > /dev/null 2>&1 | grep "^2." > /dev/null 2>&1; then # IF it not exists/work anymore try the other command COMPOSE_COMMAND="docker compose" if ! $COMPOSE_COMMAND > /dev/null 2>&1; then # IF it cannot find Native in > 2.X, then script stops - echo -e "\e[31mCannot find Docker Compose.\e[0m" + echo -e "\e[31mCannot find Docker Compose.\e[0m" echo -e "\e[31mPlease install it regarding to this doc site: https://docs.mailcow.email/install/\e[0m" exit 1 fi # If it finds the native Plugin it will use this instead and change the mailcow.conf Variable accordingly echo -e "\e[31mFound different Docker Compose Version then declared in mailcow.conf!\e[0m" echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable from standalone to native\e[0m" - sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=native/' $SCRIPT_DIR/mailcow.conf + sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=native/' "$SCRIPT_DIR/mailcow.conf" sleep 2 fi fi @@ -297,7 +297,7 @@ if [[ "$(uname -r)" =~ ^4\.15\.0-60 ]]; then fi if [[ "$(uname -r)" =~ ^4\.4\. ]]; then - if grep -q Ubuntu <<< $(uname -a); then + if grep -q Ubuntu <<< "$(uname -a)"; then echo "DO NOT RUN mailcow ON THIS UBUNTU KERNEL!" echo "Please update to linux-generic-hwe-16.04 by running \"apt-get install --install-recommends linux-generic-hwe-16.04\"" exit 1 @@ -322,10 +322,10 @@ unset COMPOSE_COMMAND unset DOCKER_COMPOSE_VERSION for bin in curl docker git awk sha1sum grep cut; do - if [[ -z $(command -v ${bin}) ]]; then - echo "Cannot find ${bin}, exiting..." + if [[ -z $(command -v ${bin}) ]]; then + echo "Cannot find ${bin}, exiting..." exit 1; - fi + fi done # Check Docker Version (need at least 24.X) @@ -340,20 +340,20 @@ fi export LC_ALL=C DATE=$(date +%Y-%m-%d_%H_%M_%S) -BRANCH=$(cd ${SCRIPT_DIR}; git rev-parse --abbrev-ref HEAD) +BRANCH="$(cd "${SCRIPT_DIR}"; git rev-parse --abbrev-ref HEAD)" while (($#)); do case "${1}" in --check|-c) echo "Checking remote code for updates..." - LATEST_REV=$(git ls-remote --exit-code --refs --quiet https://github.com/mailcow/mailcow-dockerized ${BRANCH} | cut -f1) - if [ $? -ne 0 ]; then + LATEST_REV=$(git ls-remote --exit-code --refs --quiet https://github.com/mailcow/mailcow-dockerized "${BRANCH}" | cut -f1) + if [ "$?" -ne 0 ]; then echo "A problem occurred while trying to fetch the latest revision from github." exit 99 fi if [[ -z $(git log HEAD --pretty=format:"%H" | grep "${LATEST_REV}") ]]; then echo -e "Updated code is available.\nThe changes can be found here: https://github.com/mailcow/mailcow-dockerized/commits/master" - git log --date=short --pretty=format:"%ad - %s" $(git rev-parse --short HEAD)..origin/master + git log --date=short --pretty=format:"%ad - %s" "$(git rev-parse --short HEAD)"..origin/master exit 0 else echo "No updates available." @@ -370,7 +370,7 @@ while (($#)); do SKIP_PING_CHECK=y ;; --stable) - CURRENT_BRANCH="$(cd ${SCRIPT_DIR}; git rev-parse --abbrev-ref HEAD)" + CURRENT_BRANCH="$(cd "${SCRIPT_DIR}"; git rev-parse --abbrev-ref HEAD)" NEW_BRANCH="master" ;; --gc) @@ -379,7 +379,7 @@ while (($#)); do exit 0 ;; --nightly) - CURRENT_BRANCH="$(cd ${SCRIPT_DIR}; git rev-parse --abbrev-ref HEAD)" + CURRENT_BRANCH="$(cd "${SCRIPT_DIR}"; git rev-parse --abbrev-ref HEAD)" NEW_BRANCH="nightly" ;; --prefetch) @@ -499,19 +499,19 @@ CONFIG_ARRAY=( detect_bad_asn sed -i --follow-symlinks '$a\' mailcow.conf -for option in ${CONFIG_ARRAY[@]}; do +for option in "${CONFIG_ARRAY[@]}"; do if [[ ${option} == "ADDITIONAL_SAN" ]]; then - if ! grep -q ${option} mailcow.conf; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo "${option}=" >> mailcow.conf fi - elif [[ ${option} == "COMPOSE_PROJECT_NAME" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "COMPOSE_PROJECT_NAME" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo "COMPOSE_PROJECT_NAME=mailcowdockerized" >> mailcow.conf fi - elif [[ ${option} == "DOCKER_COMPOSE_VERSION" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "DOCKER_COMPOSE_VERSION" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo "# Used Docker Compose version" >> mailcow.conf echo "# Switch here between native (compose plugin) and standalone" >> mailcow.conf @@ -521,73 +521,73 @@ for option in ${CONFIG_ARRAY[@]}; do echo "" >> mailcow.conf echo "DOCKER_COMPOSE_VERSION=${DOCKER_COMPOSE_VERSION}" >> mailcow.conf fi - elif [[ ${option} == "DOVEADM_PORT" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "DOVEADM_PORT" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo "DOVEADM_PORT=127.0.0.1:19991" >> mailcow.conf fi - elif [[ ${option} == "WATCHDOG_NOTIFY_EMAIL" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "WATCHDOG_NOTIFY_EMAIL" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo "WATCHDOG_NOTIFY_EMAIL=" >> mailcow.conf fi - elif [[ ${option} == "LOG_LINES" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "LOG_LINES" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Max log lines per service to keep in Redis logs' >> mailcow.conf echo "LOG_LINES=9999" >> mailcow.conf fi - elif [[ ${option} == "IPV4_NETWORK" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "IPV4_NETWORK" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Internal IPv4 /24 subnet, format n.n.n. (expands to n.n.n.0/24)' >> mailcow.conf echo "IPV4_NETWORK=172.22.1" >> mailcow.conf fi - elif [[ ${option} == "IPV6_NETWORK" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "IPV6_NETWORK" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Internal IPv6 subnet in fc00::/7' >> mailcow.conf echo "IPV6_NETWORK=fd4d:6169:6c63:6f77::/64" >> mailcow.conf fi - elif [[ ${option} == "SQL_PORT" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "SQL_PORT" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Bind SQL to 127.0.0.1 on port 13306' >> mailcow.conf echo "SQL_PORT=127.0.0.1:13306" >> mailcow.conf fi - elif [[ ${option} == "API_KEY" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "API_KEY" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Create or override API key for web UI' >> mailcow.conf echo "#API_KEY=" >> mailcow.conf fi - elif [[ ${option} == "API_KEY_READ_ONLY" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "API_KEY_READ_ONLY" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Create or override read-only API key for web UI' >> mailcow.conf echo "#API_KEY_READ_ONLY=" >> mailcow.conf fi - elif [[ ${option} == "API_ALLOW_FROM" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "API_ALLOW_FROM" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Must be set for API_KEY to be active' >> mailcow.conf echo '# IPs only, no networks (networks can be set via UI)' >> mailcow.conf echo "#API_ALLOW_FROM=" >> mailcow.conf fi - elif [[ ${option} == "SNAT_TO_SOURCE" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "SNAT_TO_SOURCE" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Use this IPv4 for outgoing connections (SNAT)' >> mailcow.conf echo "#SNAT_TO_SOURCE=" >> mailcow.conf fi - elif [[ ${option} == "SNAT6_TO_SOURCE" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "SNAT6_TO_SOURCE" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Use this IPv6 for outgoing connections (SNAT)' >> mailcow.conf echo "#SNAT6_TO_SOURCE=" >> mailcow.conf fi - elif [[ ${option} == "MAILDIR_GC_TIME" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "MAILDIR_GC_TIME" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Garbage collector cleanup' >> mailcow.conf echo '# Deleted domains and mailboxes are moved to /var/vmail/_garbage/timestamp_sanitizedstring' >> mailcow.conf @@ -595,8 +595,8 @@ for option in ${CONFIG_ARRAY[@]}; do echo '# Check interval is hourly' >> mailcow.conf echo 'MAILDIR_GC_TIME=1440' >> mailcow.conf fi - elif [[ ${option} == "ACL_ANYONE" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "ACL_ANYONE" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Set this to "allow" to enable the anyone pseudo user. Disabled by default.' >> mailcow.conf echo '# When enabled, ACL can be created, that apply to "All authenticated users"' >> mailcow.conf @@ -604,96 +604,96 @@ for option in ${CONFIG_ARRAY[@]}; do echo '# Otherwise a user might share data with too many other users.' >> mailcow.conf echo 'ACL_ANYONE=disallow' >> mailcow.conf fi - elif [[ ${option} == "SOLR_HEAP" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "SOLR_HEAP" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Solr heap size, there is no recommendation, please see Solr docs.' >> mailcow.conf echo '# Solr is a prone to run OOM on large systems and should be monitored. Unmonitored Solr setups are not recommended.' >> mailcow.conf echo '# Solr will refuse to start with total system memory below or equal to 2 GB.' >> mailcow.conf echo "SOLR_HEAP=1024" >> mailcow.conf fi - elif [[ ${option} == "SKIP_SOLR" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "SKIP_SOLR" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Solr is disabled by default after upgrading from non-Solr to Solr-enabled mailcows.' >> mailcow.conf echo '# Disable Solr or if you do not want to store a readable index of your mails in solr-vol-1.' >> mailcow.conf echo "SKIP_SOLR=y" >> mailcow.conf fi - elif [[ ${option} == "ENABLE_SSL_SNI" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "ENABLE_SSL_SNI" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Create seperate certificates for all domains - y/n' >> mailcow.conf echo '# this will allow adding more than 100 domains, but some email clients will not be able to connect with alternative hostnames' >> mailcow.conf echo '# see https://wiki.dovecot.org/SSL/SNIClientSupport' >> mailcow.conf echo "ENABLE_SSL_SNI=n" >> mailcow.conf fi - elif [[ ${option} == "SKIP_SOGO" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "SKIP_SOGO" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Skip SOGo: Will disable SOGo integration and therefore webmail, DAV protocols and ActiveSync support (experimental, unsupported, not fully implemented) - y/n' >> mailcow.conf echo "SKIP_SOGO=n" >> mailcow.conf fi - elif [[ ${option} == "MAILDIR_SUB" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "MAILDIR_SUB" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# MAILDIR_SUB defines a path in a users virtual home to keep the maildir in. Leave empty for updated setups.' >> mailcow.conf echo "#MAILDIR_SUB=Maildir" >> mailcow.conf echo "MAILDIR_SUB=" >> mailcow.conf fi - elif [[ ${option} == "WATCHDOG_NOTIFY_WEBHOOK" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "WATCHDOG_NOTIFY_WEBHOOK" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Send notifications to a webhook URL that receives a POST request with the content type "application/json".' >> mailcow.conf echo '# You can use this to send notifications to services like Discord, Slack and others.' >> mailcow.conf echo '#WATCHDOG_NOTIFY_WEBHOOK=https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' >> mailcow.conf fi - elif [[ ${option} == "WATCHDOG_NOTIFY_WEBHOOK_BODY" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "WATCHDOG_NOTIFY_WEBHOOK_BODY" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# JSON body included in the webhook POST request. Needs to be in single quotes.' >> mailcow.conf echo '# Following variables are available: SUBJECT, BODY' >> mailcow.conf WEBHOOK_BODY='{"username": "mailcow Watchdog", "content": "**${SUBJECT}**\n${BODY}"}' echo "#WATCHDOG_NOTIFY_WEBHOOK_BODY='${WEBHOOK_BODY}'" >> mailcow.conf fi - elif [[ ${option} == "WATCHDOG_NOTIFY_BAN" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "WATCHDOG_NOTIFY_BAN" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Notify about banned IP. Includes whois lookup.' >> mailcow.conf echo "WATCHDOG_NOTIFY_BAN=y" >> mailcow.conf fi - elif [[ ${option} == "WATCHDOG_NOTIFY_START" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "WATCHDOG_NOTIFY_START" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Send a notification when the watchdog is started.' >> mailcow.conf echo "WATCHDOG_NOTIFY_START=y" >> mailcow.conf fi - elif [[ ${option} == "WATCHDOG_SUBJECT" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "WATCHDOG_SUBJECT" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Subject for watchdog mails. Defaults to "Watchdog ALERT" followed by the error message.' >> mailcow.conf echo "#WATCHDOG_SUBJECT=" >> mailcow.conf fi - elif [[ ${option} == "WATCHDOG_EXTERNAL_CHECKS" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "WATCHDOG_EXTERNAL_CHECKS" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Checks if mailcow is an open relay. Requires a SAL. More checks will follow.' >> mailcow.conf echo '# No data is collected. Opt-in and anonymous.' >> mailcow.conf echo '# Will only work with unmodified mailcow setups.' >> mailcow.conf echo "WATCHDOG_EXTERNAL_CHECKS=n" >> mailcow.conf fi - elif [[ ${option} == "SOGO_EXPIRE_SESSION" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "SOGO_EXPIRE_SESSION" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# SOGo session timeout in minutes' >> mailcow.conf echo "SOGO_EXPIRE_SESSION=480" >> mailcow.conf fi - elif [[ ${option} == "REDIS_PORT" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "REDIS_PORT" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo "REDIS_PORT=127.0.0.1:7654" >> mailcow.conf fi - elif [[ ${option} == "DOVECOT_MASTER_USER" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "DOVECOT_MASTER_USER" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# DOVECOT_MASTER_USER and _PASS must _both_ be provided. No special chars.' >> mailcow.conf echo '# Empty by default to auto-generate master user and password on start.' >> mailcow.conf @@ -701,22 +701,22 @@ for option in ${CONFIG_ARRAY[@]}; do echo '# LEAVE EMPTY IF UNSURE' >> mailcow.conf echo "DOVECOT_MASTER_USER=" >> mailcow.conf fi - elif [[ ${option} == "DOVECOT_MASTER_PASS" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "DOVECOT_MASTER_PASS" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# LEAVE EMPTY IF UNSURE' >> mailcow.conf echo "DOVECOT_MASTER_PASS=" >> mailcow.conf fi - elif [[ ${option} == "MAILCOW_PASS_SCHEME" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "MAILCOW_PASS_SCHEME" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Password hash algorithm' >> mailcow.conf echo '# Only certain password hash algorithm are supported. For a fully list of supported schemes,' >> mailcow.conf echo '# see https://docs.mailcow.email/models/model-passwd/' >> mailcow.conf echo "MAILCOW_PASS_SCHEME=BLF-CRYPT" >> mailcow.conf fi - elif [[ ${option} == "ADDITIONAL_SERVER_NAMES" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "ADDITIONAL_SERVER_NAMES" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Additional server names for mailcow UI' >> mailcow.conf echo '#' >> mailcow.conf @@ -728,8 +728,8 @@ for option in ${CONFIG_ARRAY[@]}; do echo 'ADDITIONAL_SERVER_NAMES=' >> mailcow.conf fi - elif [[ ${option} == "AUTODISCOVER_SAN" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "AUTODISCOVER_SAN" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Obtain certificates for autodiscover.* and autoconfig.* domains.' >> mailcow.conf echo '# This can be useful to switch off in case you are in a scenario where a reverse proxy already handles those.' >> mailcow.conf @@ -739,8 +739,8 @@ for option in ${CONFIG_ARRAY[@]}; do echo 'AUTODISCOVER_SAN=y' >> mailcow.conf fi - elif [[ ${option} == "ACME_CONTACT" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "ACME_CONTACT" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Lets Encrypt registration contact information' >> mailcow.conf echo '# Optional: Leave empty for none' >> mailcow.conf @@ -749,16 +749,16 @@ for option in ${CONFIG_ARRAY[@]}; do echo '# https://docs.mailcow.email/troubleshooting/debug-reset_tls/' >> mailcow.conf echo 'ACME_CONTACT=' >> mailcow.conf fi - elif [[ ${option} == "WEBAUTHN_ONLY_TRUSTED_VENDORS" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "WEBAUTHN_ONLY_TRUSTED_VENDORS" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo "# WebAuthn device manufacturer verification" >> mailcow.conf echo '# After setting WEBAUTHN_ONLY_TRUSTED_VENDORS=y only devices from trusted manufacturers are allowed' >> mailcow.conf echo '# root certificates can be placed for validation under mailcow-dockerized/data/web/inc/lib/WebAuthn/rootCertificates' >> mailcow.conf echo 'WEBAUTHN_ONLY_TRUSTED_VENDORS=n' >> mailcow.conf fi - elif [[ ${option} == "SPAMHAUS_DQS_KEY" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "SPAMHAUS_DQS_KEY" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo "# Spamhaus Data Query Service Key" >> mailcow.conf echo '# Optional: Leave empty for none' >> mailcow.conf @@ -767,32 +767,32 @@ for option in ${CONFIG_ARRAY[@]}; do echo '# Otherwise it will work as usual.' >> mailcow.conf echo 'SPAMHAUS_DQS_KEY=' >> mailcow.conf fi - elif [[ ${option} == "WATCHDOG_VERBOSE" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "WATCHDOG_VERBOSE" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Enable watchdog verbose logging' >> mailcow.conf echo 'WATCHDOG_VERBOSE=n' >> mailcow.conf fi - elif [[ ${option} == "SKIP_UNBOUND_HEALTHCHECK" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "SKIP_UNBOUND_HEALTHCHECK" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Skip Unbound (DNS Resolver) Healthchecks (NOT Recommended!) - y/n' >> mailcow.conf echo 'SKIP_UNBOUND_HEALTHCHECK=n' >> mailcow.conf fi - elif [[ ${option} == "DISABLE_NETFILTER_ISOLATION_RULE" ]]; then - if ! grep -q ${option} mailcow.conf; then + elif [[ "${option}" == "DISABLE_NETFILTER_ISOLATION_RULE" ]]; then + if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo '# Prevent netfilter from setting an iptables/nftables rule to isolate the mailcow docker network - y/n' >> mailcow.conf echo '# CAUTION: Disabling this may expose container ports to other neighbors on the same subnet, even if the ports are bound to localhost' >> mailcow.conf echo 'DISABLE_NETFILTER_ISOLATION_RULE=n' >> mailcow.conf - fi - elif ! grep -q ${option} mailcow.conf; then + fi + elif ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo "${option}=n" >> mailcow.conf fi done -if [[( ${SKIP_PING_CHECK} == "y")]]; then +if [[ ("${SKIP_PING_CHECK}" == "y") ]]; then echo -e "\e[32mSkipping Ping Check...\e[0m" else @@ -805,14 +805,14 @@ else fi fi -if ! [ $NEW_BRANCH ]; then +if ! [ "$NEW_BRANCH" ]; then echo -e "\e[33mDetecting which build your mailcow runs on...\e[0m" sleep 1 - if [ ${BRANCH} == "master" ]; then + if [ "${BRANCH}" == "master" ]; then echo -e "\e[32mYou are receiving stable updates (master).\e[0m" echo -e "\e[33mTo change that run the update.sh Script one time with the --nightly parameter to switch to nightly builds.\e[0m" - elif [ ${BRANCH} == "nightly" ]; then + elif [ "${BRANCH}" == "nightly" ]; then echo -e "\e[31mYou are receiving unstable updates (nightly). These are for testing purposes only!!!\e[0m" sleep 1 echo -e "\e[33mTo change that run the update.sh Script one time with the --stable parameter to switch to stable builds.\e[0m" @@ -823,12 +823,12 @@ if ! [ $NEW_BRANCH ]; then echo -e "\e[33mThe mailcow stack might still work but it is recommended to switch to the master branch (stable builds).\e[0m" echo -e "\e[33mTo change that run the update.sh Script one time with the --stable parameter to switch to stable builds.\e[0m" fi -elif [ $FORCE ]; then +elif [ "$FORCE" ]; then echo -e "\e[31mYou are running in forced mode!\e[0m" echo -e "\e[31mA Branch Switch can only be performed manually (monitored).\e[0m" echo -e "\e[31mPlease rerun the update.sh Script without the --force/-f parameter.\e[0m" sleep 1 -elif [ $NEW_BRANCH == "master" ] && [ $CURRENT_BRANCH != "master" ]; then +elif [ "$NEW_BRANCH" == "master" ] && [ "$CURRENT_BRANCH" != "master" ]; then echo -e "\e[33mYou are about to switch your mailcow updates to the stable (master) branch.\e[0m" sleep 1 echo -e "\e[33mBefore you do: Please take a backup of all components to ensure that no data is lost...\e[0m" @@ -842,21 +842,21 @@ elif [ $NEW_BRANCH == "master" ] && [ $CURRENT_BRANCH != "master" ]; then echo "OK. If you prepared yourself for that please run the update.sh Script with the --stable parameter again to trigger this process here." exit 0 fi - BRANCH=$NEW_BRANCH + BRANCH="$NEW_BRANCH" DIFF_DIRECTORY=update_diffs - DIFF_FILE=${DIFF_DIRECTORY}/diff_before_upgrade_to_master_$(date +"%Y-%m-%d-%H-%M-%S") - mv diff_before_upgrade* ${DIFF_DIRECTORY}/ 2> /dev/null + DIFF_FILE="${DIFF_DIRECTORY}/diff_before_upgrade_to_master_$(date +"%Y-%m-%d-%H-%M-%S")" + mv diff_before_upgrade* "${DIFF_DIRECTORY}/" 2> /dev/null if ! git diff-index --quiet HEAD; then echo -e "\e[32mSaving diff to ${DIFF_FILE}...\e[0m" - mkdir -p ${DIFF_DIRECTORY} - git diff ${BRANCH} --stat > ${DIFF_FILE} - git diff ${BRANCH} >> ${DIFF_FILE} + mkdir -p "${DIFF_DIRECTORY}" + git diff "${BRANCH}" --stat > "${DIFF_FILE}" + git diff "${BRANCH}" >> "${DIFF_FILE}" fi echo -e "\e[32mSwitching Branch to ${BRANCH}...\e[0m" git fetch origin - git checkout -f ${BRANCH} + git checkout -f "${BRANCH}" -elif [ $NEW_BRANCH == "nightly" ] && [ $CURRENT_BRANCH != "nightly" ]; then +elif [ "$NEW_BRANCH" == "nightly" ] && [ "$CURRENT_BRANCH" != "nightly" ]; then echo -e "\e[33mYou are about to switch your mailcow Updates to the unstable (nightly) branch.\e[0m" sleep 1 echo -e "\e[33mBefore you do: Please take a backup of all components to ensure that no Data is lost...\e[0m" @@ -874,27 +874,27 @@ elif [ $NEW_BRANCH == "nightly" ] && [ $CURRENT_BRANCH != "nightly" ]; then if ! git diff-index --quiet HEAD; then echo -e "\e[32mSaving diff to ${DIFF_FILE}...\e[0m" mkdir -p ${DIFF_DIRECTORY} - git diff ${BRANCH} --stat > ${DIFF_FILE} - git diff ${BRANCH} >> ${DIFF_FILE} + git diff "${BRANCH}" --stat > "${DIFF_FILE}" + git diff "${BRANCH}" >> "${DIFF_FILE}" fi git fetch origin - git checkout -f ${BRANCH} + git checkout -f "${BRANCH}" fi -if [ ! $DEV ]; then +if [ ! "$DEV" ]; then echo -e "\e[32mChecking for newer update script...\e[0m" - SHA1_1=$(sha1sum update.sh) + SHA1_1="$(sha1sum update.sh)" git fetch origin #${BRANCH} - git checkout origin/${BRANCH} update.sh + git checkout "origin/${BRANCH}" update.sh SHA1_2=$(sha1sum update.sh) - if [[ ${SHA1_1} != ${SHA1_2} ]]; then + if [[ "${SHA1_1}" != "${SHA1_2}" ]]; then echo "update.sh changed, please run this script again, exiting." chmod +x update.sh exit 2 fi fi -if [ ! $FORCE ]; then +if [ ! "$FORCE" ]; then read -r -p "Are you sure you want to update mailcow: dockerized? All containers will be stopped. [y/N] " response if [[ ! "${response}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then echo "OK, exiting." @@ -916,8 +916,8 @@ fi echo -e "\e[32mChecking for conflicting bridges...\e[0m" MAILCOW_BRIDGE=$($COMPOSE_COMMAND config | grep -i com.docker.network.bridge.name | cut -d':' -f2) while read NAT_ID; do - iptables -t nat -D POSTROUTING $NAT_ID -done < <(iptables -L -vn -t nat --line-numbers | grep $IPV4_NETWORK | grep -E 'MASQUERADE.*all' | grep -v ${MAILCOW_BRIDGE} | cut -d' ' -f1) + iptables -t nat -D POSTROUTING "$NAT_ID" +done < <(iptables -L -vn -t nat --line-numbers | grep "$IPV4_NETWORK" | grep -E 'MASQUERADE.*all' | grep -v "${MAILCOW_BRIDGE}" | cut -d' ' -f1) DIFF_DIRECTORY=update_diffs DIFF_FILE=${DIFF_DIRECTORY}/diff_before_update_$(date +"%Y-%m-%d-%H-%M-%S") @@ -925,8 +925,8 @@ mv diff_before_update* ${DIFF_DIRECTORY}/ 2> /dev/null if ! git diff-index --quiet HEAD; then echo -e "\e[32mSaving diff to ${DIFF_FILE}...\e[0m" mkdir -p ${DIFF_DIRECTORY} - git diff --stat > ${DIFF_FILE} - git diff >> ${DIFF_FILE} + git diff --stat > "${DIFF_FILE}" + git diff >> "${DIFF_FILE}" fi echo -e "\e[32mPrefetching images...\e[0m" @@ -948,13 +948,13 @@ done # Silently fixing remote url from andryyy to mailcow # git remote set-url origin https://github.com/mailcow/mailcow-dockerized -DEFAULT_REPO=https://github.com/mailcow/mailcow-dockerized +DEFAULT_REPO="https://github.com/mailcow/mailcow-dockerized" CURRENT_REPO=$(git config --get remote.origin.url) -if [ "$CURRENT_REPO" != "$DEFAULT_REPO" ]; then +if [ "$CURRENT_REPO" != "$DEFAULT_REPO" ]; then echo "The Repository currently used is not the default Mailcow Repository." echo "Currently Repository: $CURRENT_REPO" echo "Default Repository: $DEFAULT_REPO" - if [ ! $FORCE ]; then + if [ ! "$FORCE" ]; then read -r -p "Should it be changed back to default? [y/N] " repo_response if [[ "$repo_response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then git remote set-url origin $DEFAULT_REPO @@ -965,7 +965,7 @@ if [ "$CURRENT_REPO" != "$DEFAULT_REPO" ]; then fi fi -if [ ! $DEV ]; then +if [ ! "$DEV" ]; then echo -e "\e[32mCommitting current status...\e[0m" [[ -z "$(git config user.name)" ]] && git config user.name moo [[ -z "$(git config user.email)" ]] && git config user.email moo@cow.moo @@ -976,7 +976,7 @@ if [ ! $DEV ]; then git fetch origin #${BRANCH} echo -e "\e[32mMerging local with remote code (recursive, strategy: \"${MERGE_STRATEGY:-theirs}\", options: \"patience\"...\e[0m" git config merge.defaultToUpstream true - git merge -X${MERGE_STRATEGY:-theirs} -Xpatience -m "After update on ${DATE}" + git merge -X"${MERGE_STRATEGY:-theirs}" -Xpatience -m "After update on ${DATE}" # Need to use a variable to not pass return codes of if checks MERGE_RETURN=$? if [[ ${MERGE_RETURN} == 128 ]]; then @@ -995,7 +995,7 @@ if [ ! $DEV ]; then echo "Run $COMPOSE_COMMAND up -d to restart your stack without updates or try again after fixing the mentioned errors." exit 1 fi -elif [ $DEV ]; then +elif [ "$DEV" ]; then echo -e "\e[33mDEVELOPER MODE: Not creating a git diff and commiting it to prevent development stuff within a backup diff...\e[0m" fi @@ -1042,7 +1042,7 @@ fi # Set app_info.inc.php if [ ${BRANCH} == "master" ]; then - mailcow_git_version=$(git describe --tags `git rev-list --tags --max-count=1`) + mailcow_git_version=$(git describe --tags $(git rev-list --tags --max-count=1)) elif [ ${BRANCH} == "nightly" ]; then mailcow_git_version=$(git rev-parse --short $(git rev-parse @{upstream})) mailcow_last_git_version="" @@ -1051,7 +1051,7 @@ else mailcow_last_git_version="" fi -mailcow_git_commit=$(git rev-parse origin/${BRANCH}) +mailcow_git_commit=$(git rev-parse "origin/${BRANCH}") mailcow_git_commit_date=$(git log -1 --format=%ci @{upstream} ) if [ $? -eq 0 ]; then From f9a7712025db1b6118afc37941e30e3e8c473f95 Mon Sep 17 00:00:00 2001 From: Hassan A Hashim Date: Tue, 20 Aug 2024 09:08:34 +0300 Subject: [PATCH 133/138] Replace weird character to the correct `'` (#6029) * Replace weird character to the correct `'` * Replace final weird character, just found. --- generate_config.sh | 4 ++-- update.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/generate_config.sh b/generate_config.sh index 4d8fcd26..f5a2a01b 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -41,7 +41,7 @@ if docker compose > /dev/null 2>&1; then echo -e "\e[33mFound Docker Compose Plugin (native).\e[0m" echo -e "\e[33mSetting the DOCKER_COMPOSE_VERSION Variable to native\e[0m" sleep 2 - echo -e "\e[33mNotice: You´ll have to update this Compose Version via your Package Manager manually!\e[0m" + echo -e "\e[33mNotice: You'll have to update this Compose Version via your Package Manager manually!\e[0m" else echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m" echo -e "\e[31mPlease update/install it manually regarding to this doc site: https://docs.mailcow.email/install/\e[0m" @@ -206,7 +206,7 @@ if [[ ${SKIP_BRANCH} != y ]]; then sleep 1 while [ -z "${MAILCOW_BRANCH}" ]; do - read -r -p "Choose the Branch with it´s number [1/2] " branch + read -r -p "Choose the Branch with it's number [1/2] " branch case $branch in [2]) MAILCOW_BRANCH="nightly" diff --git a/update.sh b/update.sh index 6195c4fe..1f61ba99 100755 --- a/update.sh +++ b/update.sh @@ -404,7 +404,7 @@ while (($#)); do --nightly - Switch your mailcow updates to the unstable (nightly) branch. FOR TESTING PURPOSES ONLY!!!! --prefetch - Only prefetch new images and exit (useful to prepare updates) --skip-start - Do not start mailcow after update - --skip-ping-check - Skip ICMP Check to public DNS resolvers (Use it only if you´ve blocked any ICMP Connections to your mailcow machine) + --skip-ping-check - Skip ICMP Check to public DNS resolvers (Use it only if you've blocked any ICMP Connections to your mailcow machine) --stable - Switch your mailcow updates to the stable (master) branch. Default unless you changed it with --nightly. -f|--force - Force update, do not ask questions -d|--dev - Enables Developer Mode (No Checkout of update.sh for tests) From 567ebbc324496f1a6a36867a29470c648bcc409e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A9lano?= Date: Tue, 20 Aug 2024 13:39:20 +0200 Subject: [PATCH 134/138] Pushover/Quarantine utf 8 fix - fixes #6028 (#6031) * Decode rspamd-subject for pushover notifications Fixes #6028 * Apply iconv_mime_decode to the quarantine function as well This might contain utf-8 encoded text as well * Moved the iconv_mime_decode "fix" back to pipe.php --- data/conf/rspamd/meta_exporter/pipe.php | 2 +- data/conf/rspamd/meta_exporter/pushover.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/conf/rspamd/meta_exporter/pipe.php b/data/conf/rspamd/meta_exporter/pipe.php index 88e66e8e..1858ee66 100644 --- a/data/conf/rspamd/meta_exporter/pipe.php +++ b/data/conf/rspamd/meta_exporter/pipe.php @@ -52,7 +52,7 @@ $headers = getallheaders(); $qid = $headers['X-Rspamd-Qid']; $fuzzy = $headers['X-Rspamd-Fuzzy']; -$subject = $headers['X-Rspamd-Subject']; +$subject = iconv_mime_decode($headers['X-Rspamd-Subject']); $score = $headers['X-Rspamd-Score']; $rcpts = $headers['X-Rspamd-Rcpt']; $user = $headers['X-Rspamd-User']; diff --git a/data/conf/rspamd/meta_exporter/pushover.php b/data/conf/rspamd/meta_exporter/pushover.php index 10265d15..f122b281 100644 --- a/data/conf/rspamd/meta_exporter/pushover.php +++ b/data/conf/rspamd/meta_exporter/pushover.php @@ -53,7 +53,7 @@ $qid = $headers['X-Rspamd-Qid']; $rcpts = $headers['X-Rspamd-Rcpt']; $sender = $headers['X-Rspamd-From']; $ip = $headers['X-Rspamd-Ip']; -$subject = $headers['X-Rspamd-Subject']; +$subject = iconv_mime_decode($headers['X-Rspamd-Subject']); $messageid= $json_body->message_id; $priority = 0; From bb7fd483f7762a5df55acdd4463b70e0409849fb Mon Sep 17 00:00:00 2001 From: Hassan A Hashim Date: Tue, 20 Aug 2024 15:08:08 +0300 Subject: [PATCH 135/138] Fix: Escape a `'` character in `update.sh` (#6034) --- update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update.sh b/update.sh index 1f61ba99..dcc2020e 100755 --- a/update.sh +++ b/update.sh @@ -404,7 +404,7 @@ while (($#)); do --nightly - Switch your mailcow updates to the unstable (nightly) branch. FOR TESTING PURPOSES ONLY!!!! --prefetch - Only prefetch new images and exit (useful to prepare updates) --skip-start - Do not start mailcow after update - --skip-ping-check - Skip ICMP Check to public DNS resolvers (Use it only if you've blocked any ICMP Connections to your mailcow machine) + --skip-ping-check - Skip ICMP Check to public DNS resolvers (Use it only if you'\''ve blocked any ICMP Connections to your mailcow machine) --stable - Switch your mailcow updates to the stable (master) branch. Default unless you changed it with --nightly. -f|--force - Force update, do not ask questions -d|--dev - Enables Developer Mode (No Checkout of update.sh for tests) From 89398c47263d3e1682ef30a4f38b87401a7fe7dd Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Tue, 20 Aug 2024 14:22:55 +0200 Subject: [PATCH 136/138] Before update on 2024-08-20_14_22_10 --- docker-compose.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index cf0a028f..16789083 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -613,36 +613,6 @@ services: aliases: - ofelia - ipv6nat-mailcow: - depends_on: - - unbound-mailcow - - mysql-mailcow - - redis-mailcow - - clamd-mailcow - - rspamd-mailcow - - php-fpm-mailcow - - sogo-mailcow - - dovecot-mailcow - - postfix-mailcow - - memcached-mailcow - - nginx-mailcow - - acme-mailcow - - netfilter-mailcow - - watchdog-mailcow - - dockerapi-mailcow - - solr-mailcow - environment: - - TZ=${TZ} - image: robbertkl/ipv6nat - security_opt: - - label=disable - restart: always - privileged: true - network_mode: "host" - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - - /lib/modules:/lib/modules:ro - networks: mailcow-network: driver: bridge From 75f18df1435b72cb827af1f114f58de92c498f5e Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Fri, 23 Aug 2024 09:54:10 +0200 Subject: [PATCH 137/138] Revert "Before update on 2024-08-20_14_22_10" This reverts commit 89398c47263d3e1682ef30a4f38b87401a7fe7dd. --- docker-compose.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 16789083..cf0a028f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -613,6 +613,36 @@ services: aliases: - ofelia + ipv6nat-mailcow: + depends_on: + - unbound-mailcow + - mysql-mailcow + - redis-mailcow + - clamd-mailcow + - rspamd-mailcow + - php-fpm-mailcow + - sogo-mailcow + - dovecot-mailcow + - postfix-mailcow + - memcached-mailcow + - nginx-mailcow + - acme-mailcow + - netfilter-mailcow + - watchdog-mailcow + - dockerapi-mailcow + - solr-mailcow + environment: + - TZ=${TZ} + image: robbertkl/ipv6nat + security_opt: + - label=disable + restart: always + privileged: true + network_mode: "host" + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - /lib/modules:/lib/modules:ro + networks: mailcow-network: driver: bridge From 37beed6ad93f259b97cad41877982bce95295629 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Mon, 26 Aug 2024 09:56:49 +0200 Subject: [PATCH 138/138] update FUNDING.yml --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 11402129..71cd7eda 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1,2 @@ +github: mailcow custom: ["https://www.servercow.de/mailcow?lang=en#sal"]