From 07ac195fea271212f23fa59b176e426207293a9a Mon Sep 17 00:00:00 2001 From: milkmaker Date: Wed, 18 May 2022 18:20:03 +0200 Subject: [PATCH 01/52] Translations update from Weblate (#4591) * [Web] Updated lang.ru.json [CI SKIP] Co-authored-by: DRago_Angel Co-authored-by: milkmaker * [Web] Updated lang.uk.json [CI SKIP] [Web] Updated lang.uk.json [CI SKIP] [Web] Added lang.uk.json [CI SKIP] Co-authored-by: OGudzik Co-authored-by: Oleksii Kruhlenko Co-authored-by: Peter Co-authored-by: milkmaker * [Web] Updated lang.it.json [CI SKIP] Co-authored-by: Stefano Co-authored-by: milkmaker * Add Ukrainian language code in vars.inc.php Co-authored-by: DRago_Angel Co-authored-by: OGudzik Co-authored-by: Oleksii Kruhlenko Co-authored-by: Peter Co-authored-by: Stefano --- data/web/inc/vars.inc.php | 1 + data/web/lang/lang.it.json | 13 +- data/web/lang/lang.ru.json | 19 +- data/web/lang/lang.uk.json | 1186 ++++++++++++++++++++++++++++++++++++ 4 files changed, 1206 insertions(+), 13 deletions(-) create mode 100644 data/web/lang/lang.uk.json diff --git a/data/web/inc/vars.inc.php b/data/web/inc/vars.inc.php index 62e5f909..c8e79bc4 100644 --- a/data/web/inc/vars.inc.php +++ b/data/web/inc/vars.inc.php @@ -100,6 +100,7 @@ $AVAILABLE_LANGUAGES = array( 'ru' => 'Pусский (Russian)', 'sk' => 'Slovenčina (Slovak)', 'sv' => 'Svenska (Swedish)', + 'uk' => 'Українська (Ukrainian)', 'zh' => '中文 (Chinese)' ); diff --git a/data/web/lang/lang.it.json b/data/web/lang/lang.it.json index 1ab2720a..569951e0 100644 --- a/data/web/lang/lang.it.json +++ b/data/web/lang/lang.it.json @@ -2,8 +2,8 @@ "acl": { "alias_domains": "Aggiungi alias di dominio", "app_passwds": "Gestisci le password delle app", - "bcc_maps": "BCC maps", - "delimiter_action": "Delimiter action", + "bcc_maps": "Mappe CCN", + "delimiter_action": "Azione delimitatrice", "domain_desc": "Modifica la descrizione del dominio", "domain_relayhost": "Modifica relayhost per un dominio", "eas_reset": "Ripristina i dispositivi EAS", @@ -106,7 +106,8 @@ "validate": "Convalida", "validation_success": "Convalidato con successo", "bcc_dest_format": "Il destinatario in copia nascosta deve essere un singolo indirizzo email.
Se si vuole spedire una copia del messaggio a più destinatari, bisogna creare un alias ed utilizzarlo per questa opzione.", - "app_passwd_protocols": "Protocolli consentiti per la password dell'app" + "app_passwd_protocols": "Protocolli consentiti per la password dell'app", + "tags": "Tag" }, "admin": { "access": "Accedi", @@ -983,7 +984,7 @@ "enter_qr_code": "Il codice TOTP se il tuo dispositivo non è in grado di acquisire i codici QR", "error_code": "Codice di errore", "init_webauthn": "Inizializzazione, attendere prego...", - "key_id": "Identificatore per il tuo YubiKey", + "key_id": "Identificatore per il tuo dispositivo", "key_id_totp": "Identificatore per la tua chiave", "none": "Disattivato", "reload_retry": "- (ricaricare la pagina se l'errore persiste)", @@ -997,7 +998,9 @@ "waiting_usb_auth": "In attesa del device USB...

Tocca ora il pulsante sul dispositivo WebAuthn USB.", "waiting_usb_register": "In attesa del device USB...

Inserisci la tua password qui sopra e conferma la tua registrazione WebAuthn toccando il pulsante del dispositivo WebAuthn USB.", "yubi_otp": "Autenticazione Yubico OTP", - "tfa_token_invalid": "Token TFA non valido" + "tfa_token_invalid": "Token TFA non valido", + "u2f_deprecated": "Sembra che la tua chiave sia stata registrata utilizzando il metodo U2F deprecato. Disattiveremo Two-Factor-Authenticaiton per te e cancelleremo la tua chiave.", + "u2f_deprecated_important": "Registra la tua chiave nel pannello di amministrazione con il nuovo metodo WebAuthn." }, "user": { "action": "Azione", diff --git a/data/web/lang/lang.ru.json b/data/web/lang/lang.ru.json index 34b331ad..dd1418e4 100644 --- a/data/web/lang/lang.ru.json +++ b/data/web/lang/lang.ru.json @@ -105,7 +105,9 @@ "timeout2": "Тайм-аут для подключения к локальному хосту", "username": "Имя пользователя", "validate": "Проверить", - "validation_success": "Проверка прошла успешно" + "validation_success": "Проверка прошла успешно", + "tags": "Теги", + "app_passwd_protocols": "Разрешенные протоколы для пароля приложения" }, "admin": { "access": "Настройки доступа", @@ -190,7 +192,7 @@ "flush_queue": "Отправить все сообщения", "forwarding_hosts": "Переадресация хостов", "forwarding_hosts_add_hint": "Можно указывать: IPv4/IPv6 подсети в нотации CIDR, имена хостов (которые будут разрешаться в IP-адреса) или доменные имена (которые будут решаться с IP-адресами путем запроса SPF записей или, в случае их отсутствия - запросом MX записей).", - "forwarding_hosts_hint": "Входящие сообщения безоговорочно принимаются от любых хостов, перечисленных здесь. Эти хосты не проходят проверку DNSBL и graylisting. Спам, полученный от них, никогда не отклоняется, но при желании можно включить спам фильтр и письма с плохим рейтингом будут попадать в Junk. Наиболее распространенное использование - указать почтовые серверы, на которых вы установили правило, которое перенаправляет входящие электронные письма на ваш почтовый сервер.", + "forwarding_hosts_hint": "Входящие сообщения безоговорочно принимаются от любых хостов, перечисленных здесь. Эти хосты не проходят проверку DNSBL и graylisting. Спам, полученный от них, никогда не отклоняется, но при желании можно включить спам фильтр и письма с плохим рейтингом будут попадать в Junk. Наиболее распространенное использование - указать почтовые серверы, на которых вы установили правило, которое перенаправляет входящие электронные письма на ваш почтовый сервер mailcow.", "from": "От", "generate": "сгенерировать", "guid": "GUID - уникальный ID", @@ -460,7 +462,8 @@ "unlimited_quota_acl": "Неограниченная квота запрещена политикой доступа", "username_invalid": "Имя пользователя %s нельзя использовать", "validity_missing": "Пожалуйста, назначьте срок действия", - "value_missing": "Пожалуйста заполните все поля" + "value_missing": "Пожалуйста заполните все поля", + "yotp_verification_failed": "Ошибка валидации Yubico OTP: %s" }, "debug": { "chart_this_server": "Диаграмма (текущий сервер)", @@ -886,11 +889,11 @@ "type": "Тип" }, "ratelimit": { - "disabled": "Отключен", - "second": "сообщений / секунду", - "minute": "сообщений / минуту", - "hour": "сообщений / час", - "day": "сообщений / день" + "disabled": "Отключен", + "second": "сообщений / секунду", + "minute": "сообщений / минуту", + "hour": "сообщений / час", + "day": "сообщений / день" }, "start": { "help": "Справка", diff --git a/data/web/lang/lang.uk.json b/data/web/lang/lang.uk.json new file mode 100644 index 00000000..0b8df84e --- /dev/null +++ b/data/web/lang/lang.uk.json @@ -0,0 +1,1186 @@ +{ + "acl": { + "bcc_maps": "Правила BCC", + "delimiter_action": "Обробка тегованої пошти", + "prohibited": "Заборонено правилами ACL", + "quarantine_category": "Категорія повідомлень про спам", + "recipient_maps": "Перезапис одержувача", + "smtp_ip_access": "Налаштування дозволених IP для SMTP", + "sogo_access": "Управління доступом до SOGo", + "spam_score": "Політика фільтрації спаму", + "protocol_access": "Налаштування дозволених протоколів", + "quarantine_notification": "Сповіщення про спам", + "tls_policy": "Політика шифрування", + "domain_desc": "Змінити опис домену", + "eas_reset": "Скинути пристрої EAS", + "extend_sender_acl": "Дозволити розширювати ACL відправника за зовнішніми адресами", + "filters": "Фільтри", + "mailbox_relayhost": "Змінити relayhost для поштової скриньки", + "pushover": "Pushover", + "quarantine": "Карантинні дії", + "quarantine_attachments": "Карантинні вкладення", + "ratelimit": "Обмеження відправки", + "spam_alias": "Тимчасові псевдоніми", + "spam_policy": "Чорний та білий списки", + "syncjobs": "Завдання синхронізації", + "unlimited_quota": "Необмежена квота для поштових скриньок", + "alias_domains": "Додати псевдоніми домену", + "app_passwds": "Паролі додатків", + "domain_relayhost": "Змінити relayhost для домену", + "login_as": "Увійти як користувач поштової скриньки", + "sogo_profile_reset": "Скинути профіль SOGo" + }, + "add": { + "app_name": "Назва додатка", + "app_password": "Додати пароль додатка", + "app_passwd_protocols": "Дозволені протоколи для пароля додатка", + "comment_info": "Приватний коментар не видно користувачам, а публічний – відображається поряд із псевдонімом в особистому кабінеті користувача.", + "custom_params": "Налаштування користувача", + "gal": "GAL - Глобальна адресна книга", + "mailbox_quota_m": "Максимальна квота поштового акаунту (MiB)", + "max_aliases": "Максимум псевдонімів", + "max_mailboxes": "Максимум поштових скриньок", + "mins_interval": "Інтервал (у хвилинах)", + "multiple_bookings": "Декілька бронювань", + "nexthop": "Наступний хост", + "password": "Пароль", + "port": "Порт", + "private_comment": "Приватний коментар", + "public_comment": "Публічний коментар", + "quota_mb": "Квота (МіБ)", + "relay_all": "Ретрансляція всіх отримувачів", + "relay_domain": "Ретрансляція цього домену", + "relay_unknown_only": "Ретрансляція лише неіснуючих поштових скриньок. Пошта до існуючих поштових скриньок доставлятиметься локально.", + "select": "Будь ласка, оберіть...", + "select_domain": "Будь ласка, спочатку виберіть домен", + "sieve_desc": "Короткий опис", + "sieve_type": "Тип фільтра", + "skipcrossduplicates": "Пропускати в папках повідомлення, що повторюються", + "subscribeall": "Підписатися на всі папки та підпапки", + "syncjob": "Додати завдання синхронізації", + "tags": "Мітки", + "target_address": "Власники псевдоніму", + "target_address_info": "Адреси поштових скриньок, розділені комами.", + "target_domain": "Цільовий домен", + "timeout2": "Тайм-аут для підключення до локального хоста", + "username": "Ім'я користувача", + "validate": "Перевірити", + "validation_success": "Перевірка пройшла успішно", + "activate_filter_warn": "Активація цього фільтра відключить решту фільтрів цього типу.", + "alias_address_info": "Вкажіть поштові адреси розділені комами або, якщо хочете пересилати всі повідомлення для домену власникам псевдоніму: @example.com. Дозволені тільки домени mailcow.", + "automap": "Автоматичне зіставлення папок (\"Надіслані листи\", \"Надіслані\" => \"Надіслані\" тощо)", + "backup_mx_options": "Параметри резервного MX", + "bcc_dest_format": "Призначення BCC має бути єдиною дійсною адресою електронної пошти.
Якщо вам потрібно надіслати копію на декілька адрес - використовуйте псевдонім.", + "gal_info": "GAL містить усі об'єкти домену і не може бути відредагований. Інформація про зайнятість у SOGo буде відсутня для домену, якщо ця функція не буде увімкнена! Щоб зміни застосувалися, потрібно перезапустити SOGo.", + "mailbox_quota_def": "Квота поштового акаунту за замовчуванням", + "mailbox_username": "Ім'я користувача (частина адреси електронної пошти ліворуч)", + "password_repeat": "Підтвердження пароля (повтор)", + "post_domain_add": "Після додавання нового домену контейнер SOGo (\"sogo-mailcow\") необхідно перезапустити!

Крім того, слід перевірити конфігурацію DNS доменів. Після затвердження конфігурації DNS перезапустіть контейнер \"acme-mailcow\", щоб автоматично згенерувати сертифікати для вашого нового домену.
Цей крок не є обов'язковим і повторюватиметься кожні 24 години.", + "relay_all_info": "Якщо ви вирішите не ретранслювати всіх одержувачів, вам потрібно буде додати (\"сліпу\") поштову адресу для кожного одержувача, якого слід ретранслювати.", + "relay_transport_info": "
Інфо
Ви можете налаштувати власний транспорт для домену. Якщо такої установки немає, то доставка буде виконана на основі MX-записів.", + "relayhost_wrapped_tls_info": "Будь ласка, не використовуйте TLS порти (в основному це 465 порт).
\nВикористовуйте будь-який не порт TLS, який підтримує STARTTLS. А для захисту від downgrate атак - налаштуйте примусову політику TLS.", + "syncjob_hint": "Паролі до вашого акаунту будуть збережені на сервері у вигляді простого тексту!", + "timeout1": "Тайм-аут для підключення до віддаленого хоста", + "active": "Активний", + "add": "Додати", + "add_domain_only": "Додати лише домен", + "add_domain_restart": "Додати домен і перезапустити SOGo", + "alias_address": "Псевдонім/и", + "alias_domain": "Псевдонім домена", + "alias_domain_info": "Лише дійсні доменні імена (розділені комами).", + "custom_params_hint": "Правильно: --param=xy, неправильно: --param xy", + "delete2": "Видалити повідомлення на місці призначення, які не є в джерелі", + "description": "Опис", + "destination": "Призначення", + "disable_login": "Заборонити вхід (вхідна пошта все ще приймається)", + "domain": "Домен", + "domain_matches_hostname": "Домен %s відповідає імені хосту", + "enc_method": "Метод шифрування", + "exclude": "Виключити об'єкти (regex)", + "full_name": "Повне ім'я", + "generate": "згенерувати", + "goto_ham": "Запам'ятати як корисну пошту", + "goto_null": "Вимкнути вхідну пошту", + "goto_spam": "Запам'ятати як спам", + "hostname": "Ім'я хоста", + "inactive": "Неактивний", + "kind": "Вид", + "delete1": "Видалити з джерела після завершення", + "delete2duplicates": "Видалити дублікати на місці призначення", + "domain_quota_m": "Загальна квота домену (МіБ)" + }, + "admin": { + "access": "Налаштування доступу", + "action": "Дії", + "activate_send": "Активувати кнопку відправки", + "active": "Активний", + "add": "Додати", + "add_admin": "Додати адміністратора", + "add_domain_admin": "Додати адміністратора домену", + "add_forwarding_host": "Додати перенаправлення вузла", + "add_row": "Додати рядок", + "add_settings_rule": "Додати правило", + "add_transport": "Додати маршрут", + "add_transports_hint": "Будь ласка, майте на увазі, що дані для автентифікації зберігатимуться у вигляді звичайного тексту.", + "additional_rows": " додано додаткові рядки", + "admin": "Адміністратор", + "admin_details": "Змінити дані адміністратора", + "admins": "Адміністратори", + "admins_ldap": "Адміністратори LDAP", + "api_info": "API знаходиться на стадії розробки. Документація знаходиться за адресою /api", + "api_key": "Ключ API", + "api_read_only": "Доступ лише для читання", + "api_read_write": "Доступ на читання та запис", + "app_links": "Посилання на додатки", + "app_name": "Назва додатка", + "apps_name": "Назва для \"mailcow Apps\"", + "authed_user": "Автор. корист.", + "ays": "Ви впевнені, що хочете продовжити?", + "change_logo": "Змінити логотип", + "configuration": "Глобальні налаштування", + "convert_html_to_text": "Перетворити HTML на звичайний текст", + "customer_id": "ID клієнта", + "customize": "Персоналізація", + "delete_queue": "Видалити всі повідомлення", + "destination": "Призначення", + "dkim_add_key": "Додати ARC/DKIM ключ", + "dkim_domains_selector": "Селектор", + "dkim_domains_wo_keys": "Вибрати домени з відсутніми ключами DKIM", + "dkim_from": "з", + "dkim_from_title": "Вихідний домен для копіювання ключа", + "dkim_key_length": "Довжина ключа DKIM (біт)", + "dkim_key_missing": "Ключ відсутній", + "dkim_key_unused": "Ключ не використовується", + "dkim_key_valid": "Ключ дійсний", + "dkim_keys": "ARC/DKIM ключі", + "dkim_overwrite_key": "Перезаписати наявний ключ DKIM", + "dkim_private_key": "Закритий ключ", + "dkim_to": "до", + "domain": "Домен", + "domain_admin": "Адміністратор домену", + "domain_admins": "Адміністратори домену", + "domain_s": "Домен(и)", + "duplicate": "Копіювати", + "edit": "Змінити", + "empty": "Пусто", + "f2b_ban_time": "Час бану (у секундах)", + "f2b_blacklist": "Чорний список підмереж/хостів", + "f2b_max_attempts": "Максимальна кількість спроб", + "f2b_netban_ipv4": "Розмір підмережі IPv4 для блокування (8-32)", + "f2b_netban_ipv6": "Розмір підмережі IPv6 для блокування (8-128)", + "f2b_parameters": "Налаштування Fail2ban", + "f2b_regex_info": "Журнали, які приймаються до уваги: SOGo, Postfix, Dovecot, PHP-FPM.", + "f2b_retry_window": "Проміжок часу для наступного блокування (у секундах)", + "f2b_whitelist": "Білий список підмереж/хостів", + "filter_table": "Пошук", + "forwarding_hosts": "Переадресація хостів", + "from": "Від", + "generate": "згенерувати", + "guid": "GUID – унікальний ID", + "help_text": "Замінити текст довідки на сторінці логіна (дозволено використання HTML)", + "host": "Хост", + "html": "HTML", + "import": "Імпорт", + "import_private_key": "Імпорт закритого ключа", + "in_use_by": "Використовується в", + "inactive": "Неактивний", + "include_exclude": "Включити/Виключити", + "includes": "Включити цих одержувачів", + "is_mx_based": "На основі MX", + "last_applied": "Ост. застосування", + "link": "Посилання", + "loading": "Зачекайте, будь ласка.", + "login_time": "Час входу", + "lookup_mx": "Призначення на основі резолвінгу MX-запису за регулярним виразом (.*\\.example\\.com$ для маршрутизації всієї пошти через цей хост, якщо MX закінчується на example.com)", + "main_name": "Назва для \"mailcow UI\"", + "merged_vars_hint": "Сірим кольором виділено рядки, отримані з vars.(local.)inc.php, вони не можуть бути змінені.", + "message": "Повідомлення", + "message_size": "Розмір повідомлення", + "nexthop": "Наступний хост", + "no": "✕", + "no_active_bans": "Наразі немає заблокованих хостів чи підмереж", + "no_new_rows": "Немає доступних рядків", + "no_record": "Нема записів", + "oauth2_add_client": "Додати клієнта OAuth2", + "oauth2_client_secret": "Секретний ключ користувача", + "oauth2_redirect_uri": "Переадресація URI", + "oauth2_renew_secret": "Згенерувати новий ключ клієнта", + "oauth2_revoke_tokens": "Відкликати всі клієнтські токени", + "optional": "опційно", + "password": "Пароль", + "password_length": "Мінімальна довжина пароля", + "password_policy": "Політика паролів", + "password_policy_chars": "Має містити алфавітний символ", + "password_policy_length": "Мінімальна довжина пароля %d символів", + "password_policy_lowerupper": "Має містити символи верхнього та нижнього регістрів", + "password_policy_numbers": "Має містити цифру", + "password_policy_special_chars": "Має містити спеціальний символ", + "password_repeat": "Підтвердження пароля (повтор)", + "priority": "Пріоритет", + "private_key": "Закритий ключ", + "quarantine": "Карантин", + "quarantine_exclude_domains": "Виключити домени та псевдоніми доменів", + "quarantine_max_age": "Максимальний період зберігання у днях
Значення має бути рівним або більше 1 дня.", + "quarantine_max_score": "Не повідомляти про спам, якщо оцінка листа вище, ніж:
За замовчуванням 9999.0", + "quarantine_max_size": "Максимальний розмір у МiБ (листи більшого розміру не буде збережено):
0 означає, що карантин відключено.", + "quarantine_notification_sender": "Email-адреса для надсилання повідомлення", + "quarantine_release_format": "Формат доставки листів після відновлення", + "quarantine_release_format_att": "Як додаток", + "quarantine_release_format_raw": "Оригінальний лист", + "quarantine_retention_size": "Кількість листів, які зберігаються в карантині на обліковий запис:
0 означає, що карантин відключено.", + "queue_deliver_mail": "Доставити", + "queue_hold_mail": "Поставити на утримання", + "queue_manager": "Черга на відправлення", + "queue_show_message": "Показати повідомлення", + "queue_unban": "розблокувати чергу", + "queue_unhold_mail": "Зняти з утримання", + "quota_notification_sender": "Email-адреса для надсилання повідомлення", + "quota_notification_subject": "Тема листа", + "quota_notifications": "Квота", + "quota_notifications_vars": "{{percent}} дорівнює поточній квоті користувача
{{username}} - ім'я поштового облікового запису", + "r_active": "Увімкнені обмеження", + "r_inactive": "Вимкнені обмеження", + "rate_name": "Назва черги", + "recipients": "Одержувачі", + "refresh": "Оновити", + "regen_api_key": "Створити новий ключ для API", + "regex_maps": "Фільтрування за допомогою регулярних виразів", + "relay_from": "\"Від:\"", + "relayhosts": "Маршрутизація на основі відправника", + "remove": "Видалити", + "remove_row": "Видалити рядок", + "reset_default": "Відновити за замовчуванням", + "reset_limit": "Видалити хеш", + "routing": "Маршрутизація", + "rsetting_add_rule": "Додати правило", + "rsetting_content": "Зміст правила", + "rsetting_desc": "Короткий опис", + "rsetting_no_selection": "Будь ласка, оберіть правило", + "rsetting_none": "Немає доступних правил", + "rsettings_insert_preset": "Вставити приклад \"%s\"", + "rsettings_preset_2": "Не перевіряти листи Postmaster на спам", + "rsettings_preset_3": "Дозволити лише певних відправників для поштової скриньки (використання лише як внутрішньої поштової скриньки)", + "rsettings_preset_4": "Вимкнути Rspamd для домену", + "rspamd_global_filters": "Глобальні правила фільтрації", + "rspamd_global_filters_agree": "Я розумію, що я роблю і буду обережний!", + "rspamd_global_filters_info": "Глобальні правила фільтрації містять різні види глобальних чорних та білих списків.", + "rspamd_settings_map": "Правила Rspamd", + "sal_level": "Рівень Муу", + "save": "Зберегти зміни", + "search_domain_da": "Пошук доменів", + "service": "Сервіс", + "service_id": "ID сервісу", + "source": "Джерело", + "spamfilter": "Спам-фільтр", + "subject": "Тема листа", + "success": "Успіх", + "text": "Звичайний текст", + "time": "Час", + "title": "Назва", + "title_name": "Заголовок сайту \"mailcow UI\"", + "to_top": "Повернутися до початку", + "transport_maps": "Глобальні правила маршрутизації", + "ui_footer": "Додати нижній колонтитул (дозволено використання HTML)", + "ui_header_announcement": "Оголошення", + "ui_header_announcement_active": "Активувати оголошення", + "ui_header_announcement_content": "Текст (дозволено використання HTML)", + "ui_header_announcement_select": "Виберіть тип оголошення", + "ui_header_announcement_type": "Тип", + "ui_header_announcement_type_danger": "Дуже важливе", + "ui_header_announcement_type_info": "Інфо", + "ui_header_announcement_type_warning": "Важливе", + "ui_texts": "Найменування та описи в UI", + "unban_pending": "очікує на розблокування", + "upload": "Завантажити", + "username": "Ім'я користувача", + "validate_license_now": "Перевірити ліцензію на основі GUID із сервера ліцензій", + "verify": "Перевірити", + "yes": "✓", + "activate_api": "Увімкнути API", + "active_rspamd_settings_map": "Відобразити поточні правила", + "add_relayhost": "Додавання проміжного вузла", + "add_relayhost_hint": "Будь ласка, майте на увазі, що дані для автентифікації зберігатимуться у вигляді звичайного тексту.", + "admin_domains": "Домен призначення", + "advanced_settings": "Розширені налаштування", + "api_allow_from": "Список IP-адрес для доступу до API (розділених комою або новим рядком)", + "api_skip_ip_check": "Пропустити перевірку IP для API", + "arrival_time": "Время получения (час. пояс сервера)", + "ban_list_info": "Список заблокованих IP-адрес: підмережа (час, що залишився) - [дія].
IP-адреси, що знаходяться в черзі на розблокування, будуть видалені зі списку активних блокувань протягом декількох секунд.
/>Червона мітка означає, що підмережа/хост знаходиться в чорному списку.", + "credentials_transport_warning": "Попередження: додавання нового запису перезапише облікові дані для всіх записів з таким самим наступним хостом.", + "dkim_to_title": "Цільовий домен(и) (DKIM буде перезаписаний)", + "duplicate_dkim": "Копіювання DKIM запису", + "excludes": "Виключає цих отримувачів", + "f2b_filter": "Правила фільтрування за допомогою регулярних виразів", + "f2b_list_info": "Хости або підмережі, занесені до чорного списку, завжди переважатимуть об'єкти з білого списку. Оновлення списку займе декілька секунд.", + "flush_queue": "Відправити всі повідомлення", + "forwarding_hosts_add_hint": "Можна вказувати: IPv4/IPv6 підмережі в нотації CIDR, імена хостів (які будуть дозволятися в IP-адреси) або доменні імена (які будуть вирішуватися з IP-адресами шляхом запиту SPF записів або, у разі їх відсутності, запитом MX записів).", + "forwarding_hosts_hint": "Вхідні повідомлення приймаються від будь-яких хостів, перерахованих тут. Ці хости не проходять перевірку DNSBL і greylisting. Спам, отриманий від них, ніколи не відхиляється, але за бажання можна включити спам-фільтр і листи з поганим рейтингом потраплятимуть до спаму. Найбільш поширене використання – вказати поштові сервери, на яких ви встановили правило, яке перенаправляє вхідні електронні листи на ваш поштовий сервер mailcow.", + "guid_and_license": "Ліцензія та GUID", + "hash_remove_info": "Видалення хешу лімітів відправки (якщо правило налаштовано) повністю скидає лічильники лімітів.
\n Кожен хеш позначений своїм кольором.", + "include_exclude_info": "За замовчуванням - без вибору - всі поштові скриньки адресовано", + "license_info": "Ліцензія не обов'язкова, але її придбання допомагає подальшому розвитку mailcow.
Зареєструйте свій GUID тут або придбайте підтримку для встановлення mailcow.", + "logo_info": "Ваше зображення буде зменшено до висоти 40px для верхньої навігаційної панелі і до 250px ширини для стартової сторінки.
Рекомендується використовувати векторну графіку, наприклад формату SVG.", + "oauth2_apps": "Додатки OAuth2", + "oauth2_client_id": "ID клієнта", + "oauth2_info": "Реалізація OAuth2 підтримує надання кодів авторизації та видає токени продовження сесії.
\nСервер також автоматично видає новий токен продовження сесії після того, як попередній був використаний.

\n• Scope за промовчанням: profile. Тільки користувачі поштових акаунтів можуть проходити автентифікацію через OAuth2. Якщо параметр області не вказано, він повертається до profile.
\n• Параметр state має бути відправлений клієнтом як частина запиту для авторизації.

\nШляхи для запитів OAuth2 API:
\n
    \n
  • Authorization endpoint: /oauth/authorize
  • \n
  • Token endpoint: /oauth/token
  • \n
  • Resource page: /oauth/profile
  • \n
\nГенерування нового клієнтського секрету не призводить до закінчення існуючих кодів авторизації, але вони не зможуть оновити свій токен.

\nВідкликання клієнтських токенів призведе до негайного припинення всіх активних сеансів. Усі клієнти повинні пройти повторну автентифікацію.", + "quarantine_bcc": "Надсилання копії всіх повідомлень (BCC) до одержувача:
Отримувач повинен бути внутрішнім, оскільки пошта не підписана та не перевірена.
Вимкнено, якщо одержувач не вказано.
", + "quarantine_notification_html": "Шаблон сповіщення:
Залиште порожнім, щоб відновити шаблон за промовчанням.", + "quarantine_notification_subject": "Тема листа", + "quarantine_redirect": "Перенаправити всі повідомлення цьому одержувачу:
Одержувач повинен бути внутрішнім, оскільки пошта не підписана та не перевірена.
Вимкнено, якщо одержувач не вказано.
", + "queue_ays": "Будь ласка, підтвердіть, що ви хочете видалити всі елементи з черги.", + "quota_notification_html": "Шаблон сповіщення:
Залиште порожнім, щоб відновити шаблон за замовчуванням.", + "quota_notifications_info": "Повідомлення про досягнення квоти надсилаються користувачам при досягненні 80% та 95% від встановленої квоти.", + "r_info": "Затінені/вимкнені елементи в списку активних обмежень не відомі як дійсні обмеження для mailcow і не можуть бути переміщені. Невідомі обмеження все одно будуть встановлені в порядку появи.
Ви можете додати нові елементи в inc/vars.local.inc.php, щоб мати можливість перемикати їх.", + "relay_rcpt": "\"Кому:\"", + "relay_run": "Запустити тест", + "relayhosts_hint": "Визначте проміжні вузли тут, щоб мати можливість вибрати їх у діалоговому вікні конфігурації доменів.
\n Впливає на вибрані домени, включаючи домени псевдонімів.", + "rsettings_preset_1": "Вимкнути все, окрім DKIM та обмеження швидкості для автентифікованих користувачів", + "rspamd_com_settings": "Імена правил будуть згенеровані на основі їх ID, приклади можна подивитися нижче.
Щоб дізнатися більше, перегляньте документацію Rspamd", + "rspamd_global_filters_regex": "Назви фільтрів відображають їхнє призначення. Всі правила повинні складатися з регулярних виразів у форматі \"/pattern/options\" (наприклад: /.+@domain\\.tld/i).
\nНезважаючи на те, що перед збереженням правил виконується перевірка регулярних виразів, функціональність Rspamd може бути порушена, якщо буде використан
\n некоректний синтаксис. Будьте уважні при написанні правил.
Електронні листи від адрес електронної пошти, що проходять за регулярними виразами чорних списків, будуть відхилені без збереження до карантину.
\n Rspamd спробує прочитати вміст правил за їх зміни. Але якщо ви можете перезапустити Rspamd, щоб прийняти останні зміни примусово.", + "send": "Надіслати", + "sender": "Відправник", + "sys_mails": "Системні повідомлення", + "transport_dest_format": "Регулярний вираз або: example.org, .example.org, *, box@example.org (декілька значень можуть бути розділені комами)", + "transport_test_rcpt_info": "• Використовуйте null@hosted.mailcow.de для перевірки пересилання на зовнішній пункт призначення.", + "transports_hint": "• Глобальні правила маршрутизації переважають над маршрутами на основі відправника.
\n• Переважно використовувати транспорти на основі резолвінгу MX.
\n• Користувацькі політики TLS для вихідної пошти будуть проігноровані та використовуватимуть політику TLS, налаштовану тут.
\n• Протокол для доставки завжди \"smtp:\" і тому намагатиметься використовувати TLS, якщо наступний хост підтримує його. SMTPS (TLS, найчастіше порту 465) не підтримується.
\n• Адреси відповідні \"/localhost$/\" завжди будуть доставлені \"local:\", отже політика \"*\" не поширюється на них.
\n• Щоб визначити облікові дані для наступного вузла \"[host]:25\", Postfix завжди шукає дані для \"host\" перед тим як шукати \"[host]:25\". Така поведінка унеможливлює використання \"host\" and \"[host]:25\" одночасно.", + "ui_header_announcement_help": "Оголошення видно на екрані входу в mailcow UI і всім користувачам, що ввійшли в систему.", + "unchanged_if_empty": "Якщо не змінено, залиште порожнім" + }, + "danger": { + "alias_domain_invalid": "Неприпустимий псевдонім домену: %s", + "alias_empty": "Псевдонім не може бути порожнім", + "alias_invalid": "Неприпустимий псевдонім: %s", + "aliasd_targetd_identical": "Псевдоним домена и основной домен не могут быть одинаковыми: %s", + "app_name_empty": "Назва додатку не може бути порожньою", + "app_passwd_id_invalid": "Пароль додатку ID %s неправильний", + "bcc_empty": "Призначення BCC не може бути порожнім", + "bcc_must_be_email": "Призначення BCC %s не є правильною адресою електронної пошти", + "defquota_empty": "Квота за замовчуванням не може бути 0.", + "description_invalid": "Неприпустимий опис ресурсу %s", + "dkim_domain_or_sel_exists": "Ключ DKIM для \"%s\" вже існує", + "domain_cannot_match_hostname": "Поштовий домен не може бути ім'ям хоста", + "domain_exists": "Домен %s вже існує", + "domain_invalid": "Неприпустиме ім'я домену", + "domain_not_found": "Домен %s не знайдено", + "domain_quota_m_in_use": "Квота домену має бути більше або дорівнювати %s МіБ", + "extra_acl_invalid": "Ареса зовнішнього відправника \"%s\" недійсна", + "fido2_verification_failed": "Помилка валідації FIDO2: %s", + "file_open_error": "Файл не може бути відкритий для запису", + "filter_type": "Неправильний тип фільтра", + "global_filter_write_error": "Помилка запису фільтра у файл: %s", + "global_map_invalid": "Ідентифікатор глобального правила %s недійсний", + "goto_empty": "Псевдонім повинен містити принаймні одну валідну адресу власника", + "goto_invalid": "Неприпустима основна адреса %s", + "imagick_exception": "Помилка в Imagick під час читання зображення", + "img_invalid": "Неможливо перевірити файл зображення", + "invalid_bcc_map_type": "Невірний тип правила", + "invalid_destination": "Призначення \"%s\" вказано невірно", + "invalid_filter_type": "Невірний тип фільтра", + "invalid_host": "Хост %s вказано невірно", + "invalid_nexthop": "Формат наступного хоста невірний", + "invalid_recipient_map_new": "Новий одержувач невірний: %s", + "invalid_recipient_map_old": "Початковий одержувач невірний: %s", + "ip_list_empty": "Список дозволених IP адрес не може бути порожнім", + "is_alias": "%s вже відомий як псевдонім адреси", + "is_spam_alias": "%s вже відома як тимчасова адреса псевдоніма (cпам-псевдонім)", + "last_key": "Останній ключ не можна видалити, натомість вимкніть TFA.", + "login_failed": "Введено неправильний логін або пароль", + "mailbox_invalid": "Неприпустима адреса поштового акаунту", + "mailbox_quota_left_exceeded": "Недостатньо вільного місця (місця залишилося: %d МіБ)", + "malformed_username": "Некоректне ім'я користувача", + "map_content_empty": "Зміст правила не може бути порожнім", + "max_alias_exceeded": "Перевищено максимальну кількість псевдонімів", + "max_mailbox_exceeded": "Перевищено максимальну кількість поштових скриньок (%d із %d)", + "maxquota_empty": "Максимальна квота поштового акаунту не повинна бути 0.", + "mysql_error": "Помилка MySQL: %s", + "network_host_invalid": "Мережа або хост невірні: %s", + "next_hop_interferes_any": "Існуючий хост перетинається з %s", + "nginx_reload_failed": "Не вдалося перезавантажити Nginx: %s", + "no_user_defined": "Користувач не визначений", + "object_is_not_numeric": "Значення %s не є числовим", + "password_complexity": "Пароль не відповідає вимогам", + "password_empty": "Пароль не може бути порожнім", + "policy_list_from_exists": "Запис із зазначеним ім'ям вже існує", + "policy_list_from_invalid": "Запис має неприпустимий формат", + "pushover_credentials_missing": "Токен або ключ Pushover відсутні", + "pushover_key": "Ключ Pushover вказано у неправильному форматі", + "quota_not_0_not_numeric": "Розмір квоти повинен бути більшим або дорівнювати нулю", + "recipient_map_entry_exists": "Правило перезапису \"%s\" вже існує", + "redis_error": "Ошибка в Redis: %s", + "release_send_failed": "Повідомлення не може бути відновлено: %s", + "resource_invalid": "Неприпустиме ім'я ресурсу %s", + "rl_timeframe": "Невірний часовий інтервал для ліміту відправлення", + "rspamd_ui_pw_length": "Довжина пароля повинна становити щонайменше 6 символів для Rspamd UI", + "script_empty": "Скрипт не може бути порожнім", + "set_acl_failed": "Не вдалося встановити ACL", + "settings_map_invalid": "Правило ID %s невірне", + "sieve_error": "Помилка в синтаксисі Sieve: %s", + "subject_empty": "Тема листа не може бути порожньою", + "target_domain_invalid": "Неприпустимий цільовий домен %s", + "targetd_not_found": "Цільовий домен %s не знайдено", + "temp_error": "Тимчасова помилка", + "text_empty": "Текст не повинен бути порожнім", + "tls_policy_map_entry_exists": "Правило політики шифрування \"%s\" вже існує", + "totp_verification_failed": "Помилка валідації TOTP", + "transport_dest_exists": "Призначення для відправлення \"%s\" вже існує", + "webauthn_verification_failed": "Помилка валідації WebAuthn: %s", + "unknown": "Сталася невідома помилка", + "unknown_tfa_method": "Невідомий метод TFA", + "username_invalid": "Ім'я користувача %s не можна використовувати", + "validity_missing": "Будь ласка, призначте термін дії", + "value_missing": "Будь ласка, заповніть усі поля", + "access_denied": "Доступ заборонено або вказані неправильні дані", + "alias_goto_identical": "Псевдонім та основна адреса не можуть бути ідентичними", + "aliases_in_use": "Максимальний ліміт псевдонімів повинен бути більшим або дорівнювати %d", + "bcc_exists": "Для типів %s вже існує карта BCC %s", + "comment_too_long": "Коментар задовгий, дозволено не більше 160 символів", + "dkim_domain_or_sel_invalid": "Домен або селектор DKIM неприпустимі для %s", + "domain_not_empty": "Неможливо видалити непорожній домен %s", + "extra_acl_invalid_domain": "Зовнішній відправник \"%s\" використовує недійсний домен", + "from_invalid": "Відправник не має бути порожнім", + "global_map_write_error": "Не вдалося створити глобальне правило ID %s: %s", + "ham_learn_error": "Помилка при навчанні пошти: %s", + "img_tmp_missing": "Неможливо перевірити файл зображення: тимчасовий файл не знайдено", + "invalid_mime_type": "Невірний mime type", + "invalid_nexthop_authenticated": "Наступний хост існує з різними даними авторизації, будь ласка, оновіть існуючі дані авторизації спочатку для цього хоста.", + "is_alias_or_mailbox": "%s вже відомий як псевдонім або поштовий обліковий запис", + "mailbox_defquota_exceeds_mailbox_maxquota": "Квота за замовчуванням перевищує межу максимальної квоти", + "mailbox_quota_exceeded": "Квота перевищує ліміт домену (максимум %d МіБ)", + "mailbox_quota_exceeds_domain_quota": "Максимальна квота перевищує квоту домену", + "mailboxes_in_use": "Максимальний ліміт поштових скриньок повинен бути більшим або дорівнювати %d", + "max_quota_in_use": "Квота поштового облікового запису повинна бути більшою або дорівнювати %d МіБ", + "next_hop_interferes": "%s перетинається з %s", + "object_exists": "Об'єкт %s вже існує", + "password_mismatch": "Введені паролі не співпадають", + "private_key_error": "Помилка приватного ключа: %s", + "pushover_token": "Токен Pushover вказано у неправильному форматі", + "relayhost_invalid": "Правило %s невірне", + "reset_f2b_regex": "Скидання фільтрів не було виконано за відведений проміжок часу, будь ласка, повторіть спробу або зачекайте ще кілька секунд і перезавантажте веб-сторінку.", + "sender_acl_invalid": "Неприпустиме значення ACL для %s", + "spam_learn_error": "Помилка при навчанні спам фільтра: %s", + "targetd_relay_domain": "Цільовий домен %s є доменом ретрансляції", + "tfa_token_invalid": "Невірний токен TFA", + "tls_policy_map_dest_invalid": "Неприпустиме значення призначення політики", + "tls_policy_map_parameter_invalid": "Неприпустиме значення параметра політики", + "unlimited_quota_acl": "Необмежена квота заборонена політикою доступу", + "yotp_verification_failed": "Помилка валідації Yubico OTP: %s" + }, + "debug": { + "chart_this_server": "Діаграма (цей сервер)", + "containers_info": "Статус контейнерів Docker", + "disk_usage": "Використання дискового простору", + "docs": "Проіндексовано об'єктів", + "history_all_servers": "Історія (всі сервери)", + "in_memory_logs": "Журнали контейнерів", + "last_modified": "Останні зміни", + "login_time": "Час входу", + "logs": "Журнали", + "online_users": "Підключено користувачів", + "restart_container": "Перезапустити", + "service": "Сервіс", + "size": "Розмір індексів", + "solr_dead": "Solr запускається, відключений або сламаний.", + "solr_status": "Стан Solr", + "started_at": "Запущений", + "started_on": "Запущений у", + "static_logs": "Статичні журнали", + "success": "Успіх", + "system_containers": "Система та контейнери", + "uptime": "Час роботи", + "username": "Ім'я користувача", + "external_logs": "Зовнішні журнали", + "jvm_memory_solr": "Використання оперативної пам'яті JVM", + "log_info": "

Журнали контейнерів mailcow зберігаються в Redis, і раз на хвилину рядки журналу за межами LOG_LINES (%d) видаляються, щоб зменшити навантаження на сервер.\n
Самі журнали контейнерів не зберігаються після перезавантаження контейнера. Усі контейнери додатково пишуть логи у службу Docker, і, отже, використовують драйвер логування за промовчанням. Журнали контейнерів призначені лише для налагодження дрібних проблем. Для інших завдань, будь ласка, настройте драйвер логування Docker самостійно.

\n

Зовнішні журнали збираються через API програм.

\n

Статичні журнали – це в основному журнали активності, які не записуються в Dockerd, але все одно повинні бути постійними (за винятком журналів API).

" + }, + "diagnostics": { + "cname_from_a": "Значення, отримане із запису A/AAAA. Це підтримується, поки запис вказує на правильний ресурс.", + "dns_records": "Записи DNS", + "dns_records_data": "Значення", + "dns_records_docs": "Також перегляньте документацію.", + "dns_records_name": "Назва", + "dns_records_status": "Статус", + "optional": "Цей запис необов'язковий.", + "dns_records_24hours": "Зверніть увагу, що для внесення змін до DNS може знадобитися до 24 годин, щоб правильно відобразити їхній поточний стан на цій сторінці. Ця сторінка призначена для того, щоб ви могли легко побачити, як налаштувати записи DNS і перевірити, чи всі записи правильно занесені до DNS.", + "dns_records_type": "Тип" + }, + "edit": { + "acl": "ACL (Список прав)", + "active": "Активний", + "advanced_settings": "Розширені налаштування", + "alias": "Змінити псевдонім", + "allowed_protocols": "Дозволені протоколи", + "app_name": "Назва додатка", + "app_passwd": "Пароль додатку", + "app_passwd_protocols": "Дозволені протоколи для пароля додатку", + "automap": "Автоматичне зіставлення папок (\"Надіслані листи\", \"Надіслані\" => \"Надіслані\" тощо)", + "backup_mx_options": "Параметри резервного MX", + "client_id": "ID клієнта", + "client_secret": "Секретний ключ користувача", + "delete1": "Видалити з джерела після завершення", + "delete2": "Видалити листи за місцем призначення, яких не має в джерелі", + "delete2duplicates": "Видалити дублікати за місцем призначення", + "delete_ays": "Будь ласка, підтвердіть видалення.", + "description": "Опис", + "disable_login": "Заборонити вхід (вхідна пошта все ще приймається)", + "domain": "Редагувати домен", + "domain_admin": "Редагувати адміністратора домену", + "domains": "Домени", + "edit_alias_domain": "Редагувати псевдонім домену", + "encryption": "Шифрування", + "exclude": "Виключити об'єкти (regex)", + "extended_sender_acl": "Зовнішні адреси пошти", + "force_pw_update": "Вимагати зміну пароля при наступному вході до системи", + "force_pw_update_info": "Цей користувач зможе увійти лише в %s. Паролі додатків залишаються придатними для використання.", + "full_name": "Повне ім'я", + "gal": "GAL - Глобальна адресна книга", + "generate": "згенерувати", + "grant_types": "Дозволено типи", + "hostname": "Ім'я хоста", + "inactive": "Неактивний", + "kind": "Тип", + "mailbox": "Редагувати поштову скриньку", + "max_aliases": "Максимум псевдонімів", + "max_mailboxes": "Максимум поштових скриньок", + "max_quota": "Максимальна квота поштового акаунту (МіБ)", + "maxbytespersecond": "Макс. байт у сек
(0 = без ліміту)", + "mins_interval": "Інтервал (у хвилинах)", + "multiple_bookings": "Декілька бронювань", + "none_inherit": "Відсутня / Успадковується", + "nexthop": "Наступний хост", + "password": "Пароль", + "password_repeat": "Підтвердження пароля (повтор)", + "previous": "Попередня сторінка", + "private_comment": "Приватний коментар", + "public_comment": "Публічний коментар", + "pushover": "Pushover", + "pushover_evaluate_x_prio": "Встановити високий пріоритет повідомлень для листів із високим пріоритетом [X-Priority: 1]", + "pushover_only_x_prio": "Отримувати повідомлення лише про листи з високим пріоритетом [X-Priority: 1]", + "pushover_sender_regex": "Отримувати сповіщення від відправників, що задовольняють regex-вираженню:", + "pushover_text": "Текст повідомлення", + "pushover_title": "Заголовок повідомлення", + "pushover_verify": "Перевірити доступ", + "quota_mb": "Квота (МіБ)", + "quota_warning_bcc": "Попередження про квоту BCC", + "quota_warning_bcc_info": "Попередження буде надіслано у вигляді окремих копій наступним адресатам. У дужках до теми буде надіслано відповідне ім'я користувача, наприклад: Quota warning (user@example.com).", + "ratelimit": "Ліміт відправки", + "redirect_uri": "URL-адреса переадресації/зворотний виклик", + "relay_all": "Ретрансляція всіх отримувачів", + "relay_domain": "Ретрансляція цього домену", + "relay_unknown_only": "Ретрансляція тільки існуючих поштових скриньок. Пошта до існуючих поштових скриньок доставлятиметься локально.", + "relayhost": "Маршрутизація на основі відправника", + "remove": "Видалити", + "resource": "Ресурс", + "save": "Зберегти зміни", + "scope": "Область", + "sender_acl": "Дозволити надсилати листи від імені", + "sieve_desc": "Короткий опис", + "sieve_type": "Тип фільтра", + "skipcrossduplicates": "Пропускати в папках повідомлення, що повторюються", + "sogo_access": "Надати прямий доступ до SOGo", + "sogo_access_info": "Єдиний вхід із інтерфейсу пошти продовжує працювати. Це налаштування не впливає на доступ до всіх інших служб, а також не видаляє чи змінює наявний профіль користувача SOGo.", + "sogo_visible": "Відображати псевдонім у SOGo", + "spam_alias": "Створити або змінити тимчасові (спам) псевдоніми", + "spam_filter": "Спам фільтр", + "spam_policy": "Додати або видалити елементи до білого/чорного списка", + "spam_score": "Задати індивідуальне визначення спаму", + "subfolder2": "Синхронізувати в підпапку (порожньо = в корінь)", + "syncjob": "Редагувати завдання синхронізації", + "target_domain": "Цільовий домен", + "timeout1": "Тайм-аут для підключення до віддаленого хоста", + "title": "Редагувати об’єкт", + "unchanged_if_empty": "Якщо не змінено, залиште порожнім", + "username": "Ім'я користувача", + "validate_save": "Підтвердити та зберегти", + "admin": "Редагувати адміністратора", + "allow_from_smtp": "Дозволити SMTP тільки для цих IP", + "allow_from_smtp_info": "Вкажіть IPv4/IPv6 адреси та/або підмережі.
Залиште поле порожнім, щоб дозволити відправлення з будь-яких адрес.", + "bcc_dest_format": "Призначенням правила BBC має бути єдина дійсна адреса електронної пошти.
Якщо вам потрібно надіслати копію на кілька адрес, створіть псевдонім і використовуйте його тут.", + "comment_info": "Приватний коментар не видно користувачам, а публічний - відображається поряд із псевдонімом в особистому кабінеті користувача", + "domain_quota": "Квота домену", + "dont_check_sender_acl": "Вимкнути перевірку відправника для домену %s та псевдонімів домену", + "extended_sender_acl_info": "Для зовнішніх доменів має бути імпортований або згенерований доменний ключ DKIM із відповідним записом TXT у домені, якщо зовнішній домен використовує DMARC.
\n Не забудьте додати цей сервер до відповідного запису SPF TXT зовнішнього домену.
\n Додавання домену зі списку зовнішніх адрес у mailcow автоматично видаляє відповідні записи із зовнішніх адрес користувачів.
\n Щоб дозволити користувачеві надіслати від імені *@domain.tld, вкажіть @domain.tld.", + "gal_info": "GAL містить усі об'єкти домену і не може бути відредагований. Інформація про зайнятість у SOGo буде відсутня для домену, якщо ця функція не буде увімкнена! Щоб зміни застосувалися, потрібно перезапустити SOGo.", + "lookup_mx": "Призначення на основі резолвінгу MX-запису за регулярним виразом (.*\\.example\\.com$ для маршрутизації всієї пошти через цей хост, якщо MX закінчується на example.com)", + "mailbox_quota_def": "Квота за замовчуванням", + "mailbox_relayhost_info": "Застосовується лише до поштової скриньки та особистих псевдонімів, незалежно від налаштувань маршрутизації на рівні домену.", + "maxage": "Макс. вік листів у днях для завантаження з сервера
(0 = ігнорувати вік)", + "mbox_rl_info": "Цей ліміт застосовується до SASL логіну користувача і відповідає будь-якій адресі відправника, який використовується зареєстрованим користувачем. Ліміт швидкості поштового облікового запису перекриває ліміт швидкості для всього домену.", + "pushover_info": "Установки Push-повідомлення будуть застосовуватися до всієї пошти %s (за винятком спаму), включаючи псевдоніми (особисті, загальні та теговані).", + "pushover_sender_array": "Отримувати повідомлення від списку адрес електронної пошти (розділені комами):", + "pushover_vars": "Коли фільтрація по відправнику не визначена, повідомлення будуть доставлятися від усіх відправників.
Можна використовувати звичайний фільтр по відправнику та розширений regex-фільтр, а також обидва відразу.
Придатні для використання змінні для тексту та заголовка (будь ласка, зверніть увагу на політику захисту даних)", + "relay_all_info": "↪Якщо ви вирішите не ретранслювати всіх одержувачів, вам потрібно буде додати (\"сліпий\") поштовий акаунт для кожного одержувача, якого слід ретранслювати.", + "relay_transport_info": "
Інфо
Ви можете налаштувати власний транспорт для домену. Якщо такої установки немає, то доставка буде виконана на основі MX записів.", + "sender_acl_disabled": "Перевірка відправника вимкнена", + "sender_acl_info": "Врахуйте, що якщо користувачеві поштового облікового запису А дозволено відправляти від імені користувача Б, то адреса користувача Б не з'явиться автоматично у списку \"Відправник\" при написанні листів у SOGo.
\n Користувач поштового облікового запису Б повинен створити делегування в SOGo, щоб користувач поштового облікового запису А міг вибрати його адресу як відправника. Делегування знаходиться в меню (три крапки) праворуч від імені поштового облікового запису у вікні пошти SOGo. Ця поведінка не відноситься до псевдонімів.", + "sogo_visible_info": "Впливає лише на об'єкти, які можуть відображатися в SOGo (персональні або загальні псевдоніми, що вказують щонайменше на один локальний поштовий обліковий запис). Зверніть увагу, що якщо функцію вимкнено, користувач не зможе вибрати адресу псевдоніма як відправника в SOGo.", + "target_address": "Власники псевдоніма, (розділені комами)", + "timeout2": "Тайм-аут для підключення до локального хоста" + }, + "fido2": { + "confirm": "Підтвердити", + "fido2_success": "Пристрій успішно зареєстровано", + "fido2_validation_failed": "Не вдалося перевірити", + "fn": "Назва", + "known_ids": "Відомі ID", + "none": "Вимкнено", + "rename": "Перейменувати", + "set_fido2": "Зареєструвати пристрій FIDO2", + "set_fn": "Вкажіть зрозумілу назву", + "start_fido2_validation": "Запустити процес валідації FIDO2", + "fido2_auth": "Увійти за допомогою FIDO2", + "register_status": "Статус реєстрації", + "set_fido2_touchid": "Зареєструвати Touch ID на Apple M1" + }, + "footer": { + "cancel": "Скасувати", + "confirm_delete": "Підтвердьте видалення", + "delete_now": "Видалити зараз", + "hibp_check": "Перевірити пароль на haveibeenpwned.com", + "hibp_nok": "Збіг знайдено! Це потенційно небезпечний пароль!", + "hibp_ok": "Збігів не знайдено.", + "restart_container": "Перезапустити контейнер", + "restart_now": "Перезапустити зараз", + "restarting_container": "Перезапуск контейнера, це може зайняти деякий час", + "delete_these_items": "Будь ласка, підтвердьте зміни в наступних об'єктах:", + "loading": "Зачекайте, будь ласка.", + "nothing_selected": "Нічого не вибрано", + "restart_container_info": "Важливо: повний перезапуск може зайняти деякий час, будь ласка, дочекайтеся його завершення – не оновлюйте та не закривайте сторінку." + }, + "header": { + "administration": "Налаштування сервера", + "apps": "Додатки", + "debug": "Стан сервера", + "mailboxes": "Налаштування пошти", + "quarantine": "Карантин", + "restart_netfilter": "Перезапустити netfilter", + "restart_sogo": "Перезапустити SOGo", + "user_settings": "Налаштування користувача", + "mailcow_settings": "Конфігурація" + }, + "info": { + "no_action": "Дій не передбачено", + "session_expires": "Ваш сеанс закінчиться приблизно через 15 секунд", + "awaiting_tfa_confirmation": "В очікуванні підтвердження TFA" + }, + "login": { + "fido2_webauthn": "FIDO2/WebAuthn", + "login": "Увійти", + "other_logins": "Вхід за допомогою ключа", + "password": "Пароль", + "username": "Ім'я користувача", + "delayed": "Вхід був затриманий на %s секунд.", + "mobileconfig_info": "Будь ласка, увійдіть у систему як користувач поштового облікового запису для завантаження профілю підключення Apple." + }, + "mailbox": { + "action": "Дії", + "activate": "Увімкнути", + "active": "Активний", + "add": "Додати", + "add_alias": "Додати псевдонім", + "add_alias_expand": "Копіювати псевдоніми на псевдоніми домену", + "add_bcc_entry": "Додати правило BBC", + "add_domain": "Додати домен", + "add_domain_alias": "Додати псевдонім домену", + "add_filter": "Додати фільтр", + "add_mailbox": "Додати поштову скриньку", + "add_recipient_map_entry": "Додати перезапис одержувача", + "add_resource": "Додати ресурс", + "address_rewriting": "Перезапис адрес", + "alias": "Псевдонім", + "alias_domain_backupmx": "Псевдоніми домену не можуть бути використані для домену ретрансляції", + "aliases": "Псевдоніми", + "all_domains": "Усі домени", + "allow_from_smtp": "Дозволити SMTP тільки для цих IP", + "allow_from_smtp_info": "Вкажіть IPv4/IPv6 адреси та/або підмережі.
Залиште поле порожнім, щоб дозволити відправлення з будь-яких адрес.", + "allowed_protocols": "Дозволені протоколи", + "backup_mx": "Резервний MX", + "bcc_destinations": "Назначение BCC", + "bcc_local_dest": "Локальний домен", + "bcc_map": "Правила ВВС", + "bcc_map_type": "Тип BCC", + "bcc_maps": "Правила BBC", + "bcc_rcpt_map": "Одержувач", + "bcc_sender_map": "Відправник", + "bcc_to_rcpt": "Перейти на тип \"одержувач\"", + "bcc_to_sender": "Перейти на тип \"відправник\"", + "bcc_type": "Тип BCC", + "booking_null": "Завжди показувати як вільний", + "booking_0_short": "Завжди вільний", + "booking_custom": "Ліміт на кількість бронювань", + "booking_custom_short": "Жорсткий ліміт", + "booking_ltnull": "Необмежений, зайнятий під час бронювання", + "booking_lt0_short": "М’який ліміт", + "catch_all": "Catch-all", + "daily": "Раз на день", + "description": "Опис", + "disable_x": "Вимкнути", + "domain": "Домен", + "domain_admins": "Адміністратори домену", + "domain_aliases": "Псевдоніми доменів", + "domain_quota": "Квота", + "domains": "Домени", + "edit": "Змінити", + "empty": "Пусто", + "enable_x": "Увімкнути", + "excludes": "Виключає", + "filter_table": "Пошук", + "filters": "Фильтри", + "fname": "Повне ім'я", + "goto_spam": "Запам'ятати як спам", + "hourly": "Щогодини", + "in_use": "Використано (%)", + "inactive": "Неактивний", + "insert_preset": "Вставити приклад \"%s\"", + "kind": "Тип", + "last_pw_change": "Остання зміна пароля", + "last_run": "Останній запуск", + "last_run_reset": "Наступний запуск", + "mailbox": "Поштовий акаунт", + "mailbox_defaults_info": "Визначте параметри за замовчуванням для нових поштових акаунтів.", + "mailbox_quota": "Макс. квота пошт. ящика", + "mins_interval": "Інтервал (у хвилинах)", + "msg_num": "Листів", + "multiple_bookings": "Декілька бронювань", + "never": "Ніколи", + "no": "✕", + "no_record_single": "Немає записів", + "open_logs": "Показати журнал", + "owner": "Власник", + "private_comment": "Приватний коментар", + "q_add_header": "при переміщенні до папки \"Спам\"", + "q_all": " при переміщенні в папку \"Спам\" та при відхиленні", + "q_reject": "при відхиленні", + "quarantine_notification": "Сповіщення про спам", + "quick_actions": "Дії", + "recipient": "Одержувач", + "recipient_map": "Перезапис одержувача", + "recipient_map_new": "Перезапис на", + "recipient_map_new_info": "Повинен бути чинною поштовою скринькою.", + "recipient_map_old": "Одержувач", + "recipient_maps": "Перезапис одержувача", + "remove": "Видалити", + "resources": "Ресурси", + "running": "В процесі", + "sender": "Відправник", + "set_postfilter": "Використовувати як постфільтр", + "set_prefilter": "Використати як попередній фільтр", + "sieve_preset_1": "Відкидати листи із ймовірно небезпечними типами файлів", + "sieve_preset_2": "Завжди позначати електронну пошту певного відправника як видиму", + "sieve_preset_3": "Відхилити тихо, зупинити подальшу обробку правил", + "sieve_preset_4": "Перемістити у INBOX, пропустити подальшу обробку правил", + "sieve_preset_5": "Автовідповідач (відпустка)", + "sieve_preset_6": "Відхилити лист з відповіддю", + "sieve_preset_7": "Перенаправити та зберегти/відкинути", + "sogo_visible": "Відображати псевдонім у SOGo", + "sogo_visible_n": "Не відображати псевдонім у SOGo", + "sogo_visible_y": "Відображати псевдонім у SOGo", + "spam_aliases": "Тимчасовий псевдонім", + "stats": "Статистика", + "status": "Статус", + "syncjob_check_log": "Перевірити журнал", + "syncjob_last_run_result": "Результат останнього запуску", + "syncjob_EX_OK": "Успішно", + "syncjob_EXIT_TLS_FAILURE": "Помилка встановлення шифрованого з'єднання", + "syncjob_EXIT_AUTHENTICATION_FAILURE": "Помилка авторизації", + "syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Не вдалося підключитися до віддаленого сервера", + "syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Неправильне ім'я користувача або пароль", + "table_size": "Розмір таблиці", + "table_size_show_n": "Показувати %s полів", + "target_domain": "Цільовий домен", + "tls_enforce_in": "Примусовий TLS (вхідні)", + "tls_enforce_out": "Примусовий TLS (вихідні)", + "tls_map_dest": "Призначення", + "tls_map_parameters": "Параметри", + "tls_map_policy": "Політика", + "tls_policy_maps": "Правила TLS", + "tls_policy_maps_info": "Глобальні політики перевизначають політики вихідних з'єднань TLS незалежно від налаштувань примусових політик TLS у користувачів.
\n Будь ласка, ознайомтесь з документацією \"smtp_tls_policy_maps\" для додаткової інформації.", + "tls_policy_maps_long": "Перевизначення правил для політик вихідних з'єднань TLS", + "toggle_all": "Вибрати все", + "username": "Ім'я користувача", + "waiting": "В очікуванні", + "weekly": "Раз на тиждень", + "yes": "✓", + "add_domain_record_first": "Будь ласка, спочатку додайте домен", + "add_tls_policy_map": "Додати політику TLS", + "alias_domain_alias_hint": "Псевдоніми не застосовуються до псевдонімів домену автоматично. Адреса псевдоніма my-alias@domain не охоплює адресу my-alias@alias-domain (де \"alias-domain\" – уявний псевдонім домену для \"domain\").
Використовуйте кнопку \"Скопіювати псевдоніми на псевдоніми домену\", щоб додати вибрані псевдоніми на всі псевдоніми доменів (див. вкладку \"Фільтри\" або використовуйте SOGo -> Налаштування -> Пошта -> Пересилання).", + "bcc": "Правила ВВС", + "bcc_destination": "Призначення BCC", + "bcc_info": "Правила BCC використовуються для прихованого пересилання копій усіх повідомлень на іншу адресу. Правило типу \"одержувач\" використовується, коли локальний одержувач виступає як одержувач пошти. Правило типу \"відправник\" відповідають тому самому принципу.
\n Локальний домен не буде проінформовано про невдалу доставку.", + "deactivate": "Вимкнути", + "disable_login": "Заборонити вхід (вхідна пошта все ще приймається)", + "goto_ham": "Запам'ятати як корисну пошту", + "last_mail_login": "Останній вхід", + "mailbox_defaults": "Налаштування за замовчуванням", + "mailbox_defquota": "Квота за замовчуванням", + "mailboxes": "Поштові ящики", + "no_record": "Немає записів для об'єкта %s", + "public_comment": "Публічний коментар", + "quarantine_category": "Категорія повідомлень про спам", + "recipient_map_info": "Перезапис одержувача використовується для заміни одержувача у повідомленні до його доставки.", + "recipient_map_old_info": "Має бути валідною поштовою скринькою або доменом.", + "sieve_info": "Ви можете зберегти декілька фільтрів для кожного користувача, але тільки один попередній фільтр та один постфільтр можуть бути активними одночасно.
\nКожен фільтр буде оброблено в описаному порядку. Ані зламаний скрипт, ані keep; не зупинить обробку подальших скриптів.

Global sieve prefilter • Prefilter • User scripts • Postfilter • Global sieve postfilter", + "sieve_preset_8": "Відхилити повідомлення, надіслане на псевдонім, частиною якого є відправник", + "sieve_preset_header": "Будь ласка, ознайомтесь із прикладами нижче. Для більш детальної інформації прочитайте Sieve Wikipedia.", + "sync_jobs": "Завдання синхронізації", + "syncjob_EXIT_CONNECTION_FAILURE": "Помилка зв'язку із сервером", + "syncjob_EXIT_OVERQUOTA": "Цільова поштова скринька перевищила квоту", + "target_address": "Власники псевдоніму", + "tls_map_dest_info": "Приклади: example.org, .example.org, [mail.example.org]:25", + "tls_map_parameters_info": "Залиште поле порожнім або вкажіть параметри, наприклад: protocols=!SSLv2 ciphers=medium exclude=3DES", + "tls_policy_maps_enforced_tls": "Для вихідних повідомлень від користувачів із включеною примусовою політикою шифрування вихідних з'єднань не описані глобальною політикою, будуть застосовані значення за замовчуванням, зазначені в smtp_tls_mandatory_protocols та smtp_tls_mandatory_ciphers." + }, + "oauth2": { + "authorize_app": "Авторизація додатка", + "deny": "Відмовити", + "permit": "Прийняти", + "profile": "Профіль", + "scope_ask_permission": "Додаток запросив доступ до", + "access_denied": "Будь ласка, увійдіть у систему як власник поштового облікового запису, щоб отримати доступ через OAuth2.", + "profile_desc": "Перегляд особистої інформації: ім'я користувача, повне ім'я, дата створення та зміни, статус облікового запису (активний/вимкнений)" + }, + "quarantine": { + "action": "Дії", + "atts": "Вкладення", + "check_hash": "Пошук по хешу файлу на @VT", + "confirm": "Підтвердити", + "confirm_delete": "Підтвердіть видалення цього елемента.", + "danger": "Небезпека", + "deliver_inbox": "Перемістити у \"Вхідні\"", + "download_eml": "Завантажити (.eml)", + "empty": "Пусто", + "high_danger": "Висока", + "info": "Інформація", + "junk_folder": "Небажана пошта", + "low_danger": "Низька", + "medium_danger": "Середня", + "neutral_danger": "Нейтральна", + "notified": "Повід.", + "qid": "Rspamd QID", + "qitem": "Об'єкт карантину", + "quarantine": "Карантин", + "quick_actions": "Дії", + "quick_delete_link": "Посилання для видалення", + "quick_info_link": "Посилання на дод. інформацію", + "quick_release_link": "Посилання для відновлення", + "rcpt": "Одержувач", + "received": "Отримано", + "recipients": "Одержувачі", + "refresh": "Оновити", + "rejected": "Відхилено", + "release": "Відновити", + "release_body": "Ми додали повідомлення як файл .eml до цього повідомлення.", + "release_subject": "Потенційно небезпечний лист %s", + "remove": "Видалити", + "rewrite_subject": "Змінити тему", + "rspamd_result": "Результат Rspamd", + "sender": "Відправник (SMTP)", + "sender_header": "Відправник (заголовок \"From\")", + "settings_info": "Максимальна кількість елементів, які будуть поміщені до карантину: %s
Максимальний розмір електронного листа: %s МіБ", + "show_item": "Показати", + "spam": "Спам", + "spam_score": "Оцінка", + "subj": "Тема листа", + "table_size": "Розмір таблиці", + "text_from_html_content": "Вміст листа (конвертований з html)", + "text_plain_content": "Вміст листа (text/plain)", + "toggle_all": "Вибрати все", + "type": "Тип", + "disabled_by_config": "У поточній конфігурації системи функцію карантину вимкнено.", + "learn_spam_delete": "Запам'ятати як спам та видалити", + "qhandler_success": "Запит успішно відправлено до системи. Тепер ви можете закрити вікно.", + "qinfo": "Система карантину зберігатиме відхилені листи в базі даних (у відправника не буде створене враження, що лист доставлений), а також пошту, яка буде доставлена як копія в папку «Спам» поштової скриньки.\n
\"Вивчити як спам і видалити\" вивче повідомлення як спам за теоремою Байєса і також обчислювати нечіткі хеші до денних подібних повідомлень у майбутньому.\n
Зверніть увагу, що вивчення кількох повідомлень – залежно від вашої системи – може зайняти багато часу.
Елементи чорного списку виключаються з карантину.", + "table_size_show_n": "Відображати %s полів" + }, + "ratelimit": { + "disabled": "Вимкнено", + "minute": "повідомлень / хвилину", + "hour": "повідомлень / год", + "second": "повідомлень / секунду", + "day": "повідомлень / день" + }, + "start": { + "help": "Довідка", + "mailcow_apps_detail": "Використовуйте mailcow, щоб отримати доступ до своєї пошти, календаря, контактів тощо.", + "imap_smtp_server_auth_info": "Будь ласка, використовуйте повну адресу електронної пошти у форматі user@example.com та PLAIN механізм авторизації.
\nВаші дані авторизації будуть зашифровані на рівні шифрування каналу підключення до сервера, тому переконайтеся, що ви використовуєте надійне підключення TLS.", + "mailcow_panel_detail": "Адміністратори домену можуть створювати, змінювати або видаляти поштові скриньки та псевдоніми, змінювати домени та дивитися інформацію про свої призначені домени.
Користувачі поштових скриньок мають можливість створювати тимчасові псевдоніми (спам псевдоніми), змінювати свій пароль та налаштування фільтра спаму." + }, + "success": { + "acl_saved": "ACL для %s збережено", + "admin_added": "Адміністратора %s додано", + "admin_api_modified": "Зміни в API збережено", + "admin_modified": "Зміни адміністратора збережено", + "admin_removed": "Адміністратора %s видалено", + "alias_added": "Псевдонім %s (%d) додано", + "alias_domain_removed": "Псевдонім домену %s видалено", + "alias_modified": "Зміни псевдоніма %s збережено", + "alias_removed": "Псевдонім %s видалено", + "aliasd_added": "Додано псевдонім домену %s", + "aliasd_modified": "Зберегти зміни псевдоніму домену %s", + "app_links": "Зміни посилань на додатки збережені", + "app_passwd_removed": "Пароль додатка ID %s видалено", + "bcc_deleted": "Правила BCC видалені: %s", + "bcc_edited": "Правило BCC %s відредаговано", + "bcc_saved": "Правило BCC збережено", + "delete_filter": "Фільтр ID %s видалено", + "delete_filters": "Фільтри видалені: %s", + "deleted_syncjob": "Завдання синхронізації ID %s видалено", + "dkim_added": "DKIM ключ збережений", + "dkim_duplicated": "DKIM ключі для домену %s були скопійовані в %s", + "dkim_removed": "DKIM ключ %s видалено", + "domain_added": "Додано домен %s", + "domain_admin_modified": "Зберегти зміни адміністратора домену %s", + "domain_admin_removed": "Адміністратора домену %s видалено", + "domain_removed": "Домен %s видалено", + "dovecot_restart_success": "Dovecot перезапущено успішно", + "eas_reset": "Кеш ActiveSync для користувача %s був скинутий", + "forwarding_host_added": "Перенаправлення вузла %s додано", + "forwarding_host_removed": "Перенаправлення вузла %s видалено", + "hash_deleted": "Хеш видалено", + "item_deleted": "Елемент %s успішно видалено", + "item_released": "Лист %s відновлений з карантину", + "items_released": "Вибрані листи відновлені з карантину", + "learned_ham": "Лист ID %s було вивчено як корисну пошту", + "logged_in_as": "Ви увійшли як %s", + "mailbox_added": "Поштовий акаунт %s додано", + "mailbox_modified": "Зміни поштового акаунту %s збережено", + "mailbox_removed": "Поштовий акаунт %s видалено", + "object_modified": "Зміни об'єкта %s збережено", + "password_policy_saved": "Політику паролів успішно збережено", + "qlearn_spam": "Повідомлення %s було вивчено як спам і видалено", + "queue_command_success": "Команда виконана успішно", + "recipient_map_entry_deleted": "Правило перезапису одержувача ID %s видалено", + "relayhost_added": "Проміжний вузол %s додано", + "relayhost_removed": "Проміжний вузол %s видалено", + "reset_main_logo": "Відновити логотип за замовчуванням", + "resource_added": "Ресурс %s додано", + "resource_removed": "Ресурс %s видалено", + "rl_saved": "Ліміти для %s збережені", + "rspamd_ui_pw_set": "Пароль для Rspamd успішно встановлено", + "saved_settings": "Налаштування збережено", + "settings_map_removed": "Правило ID %s видалено", + "sogo_profile_reset": "Профіль користувача SOGo %s скинуто", + "tls_policy_map_entry_saved": "Політику TLS \"%s\" збережено", + "ui_texts": "Зміни текстів UI збережено", + "upload_success": "Файл завантажено успішно", + "verified_fido2_login": "Авторизацію FIDO2 пройдено", + "verified_webauthn_login": "Авторизацію WebAuthn пройдено", + "verified_yotp_login": "Авторизацію Yubico OTP пройдено", + "app_passwd_added": "Додано новий пароль додатка", + "db_init_complete": "Ініціалізація бази даних завершена", + "deleted_syncjobs": "Завдання синхронізації видалені: %s", + "domain_admin_added": "Адміністратора домену %s додано", + "domain_modified": "Зберегти зміни домену %s", + "f2b_modified": "Зміни параметрів Fail2ban збережено", + "global_filter_written": "Фільтр успішно записано у файл", + "items_deleted": "Елемент %s успішно видалено", + "license_modified": "Зміни у ліцензії збережені", + "nginx_reloaded": "Оновлення конфігурації Nginx завершено", + "pushover_settings_edited": "Налаштування Pushover успішно встановлено. Будь ласка, перевірте облікові дані.", + "recipient_map_entry_saved": "Правило перезапису одержувача \"%s\" було збережено", + "resource_modified": "Зміни поштового акаунту %s збережено", + "settings_map_added": "Правило додано", + "tls_policy_map_entry_deleted": "Політику TLS ID %s видалено", + "verified_totp_login": "Авторизацію TOTP пройдено" + }, + "tfa": { + "confirm": "Підтвердьте", + "confirm_totp_token": "Будь-ласка, підтвердьте зміни, ввівши згенерований код", + "delete_tfa": "Вимкнути TFA", + "error_code": "Код помилки", + "init_webauthn": "Ініціалізація, будь ласка, зачекайте...", + "key_id": "Ідентифікатор вашого пристрою", + "key_id_totp": "Ідентифікатор ключа TOTP", + "none": "Вимкнути", + "scan_qr_code": "Відскануйте QR-код за допомогою додатку або введіть його вручну.", + "select": "Будь ласка, оберіть", + "start_webauthn_validation": "Розпочати перевірку", + "tfa": "Двофакторна автентифікація", + "tfa_token_invalid": "Невірний TFA токен", + "totp": "OTP (Google Authenticator, Authy та інші)", + "u2f_deprecated_important": "Будь ласка, зареєструйте свій ключ у панелі адміністратора за допомогою нового методу WebAuthn.", + "webauthn": "WebAuthn автентифікація", + "yubi_otp": "Yubico OTP автентифікація", + "api_register": "%s використовує Yubico Cloud API. Будь ласка, отримайте ключ API для вашого ключа тут", + "disable_tfa": "Вимкнути TFA до наступного успішного входу", + "enter_qr_code": "Ваш код TOTP, якщо ваш пристрій не може відсканувати QR-код", + "reload_retry": "- (перезавантажте сторінку браузера, якщо помилка не зникає)", + "set_tfa": "Встановити метод двофакторної перевірки", + "u2f_deprecated": "Схоже, ваш ключ був зареєстрований за допомогою застарілого методу U2F. Ми дезактивуємо двофакторну автентифікацію для вас і видалимо ваш ключ.", + "waiting_usb_auth": "Очікування пристрою USB...

Будь ласка, натисніть зараз кнопку на USB пристрої.", + "waiting_usb_register": "Очікування USB-пристрою...

Будь ласка, введіть пароль вище та підтвердіть реєстрацію, натиснувши кнопку на USB пристрої." + }, + "user": { + "action": "Дії", + "active": "Активний", + "active_sieve": "Увімкнені фільтри", + "advanced_settings": "Розширені налаштування", + "alias": "Псевдонім", + "alias_create_random": "Згенерувати випадковий псевдонім", + "alias_extend_all": "Продовжити псевдонім на 1 годину", + "alias_full_date": "d.m.Y, H:i:s T", + "alias_select_validity": "Період дії", + "alias_time_left": "Залишилося часу", + "alias_valid_until": "Дійсний до", + "aliases_also_send_as": "Дозволено надсилати листи від імені", + "allowed_protocols": "Дозволені протоколи", + "app_name": "Назва додатка", + "app_passwds": "Паролі додатків", + "apple_connection_profile": "Профіль підключення Apple", + "apple_connection_profile_complete": "Цей профіль включає налаштування IMAP та SMTP, а також CalDAV (календарів) та CardDAV (контактів) для пристрою Apple.", + "apple_connection_profile_mailonly": "Цей профіль включає лише налаштування IMAP та SMTP для пристрою Apple.", + "change_password": "Змінити пароль", + "change_password_hint_app_passwords": "Ваш обліковий запис містить {{number_of_app_passwords}} паролів додатків, які не змінюватимуться. Щоб керувати ними, перейдіть на вкладку \"Паролі додатків\".", + "clear_recent_successful_connections": "Очистити історію успішних підключень", + "create_app_passwd": "Створити новий пароль", + "create_syncjob": "Створити нове завдання синхронізації", + "created_on": "Дата створення", + "daily": "Раз на день", + "day": "день", + "delete_ays": "Будь ласка, підтвердіть видалення.", + "eas_reset": "Скинути кеш ActiveSync пристроїв", + "eas_reset_help": "У багатьох випадках скидання кешу пристроїв допомагає відновити пошкоджений профіль ActiveSync.
Увага: всі листи, календарі та контакти будуть завантажені заново на всі ваші пристрої!", + "eas_reset_now": "Скинути кеш зараз", + "edit": "Змінити", + "email": "Пошта", + "email_and_dav": "Пошта, календарі та контакти", + "empty": "Пусто", + "encryption": "Шифрування", + "excludes": "Виключає", + "expire_in": "Спливає через", + "fido2_webauthn": "FIDO2/WebAuthn", + "from": "від", + "generate": "згенерувати", + "hour": "година", + "hourly": "Раз на годину", + "hours": "годин", + "in_use": "Використовується", + "interval": "Інтервал", + "last_mail_login": "Останній вхід", + "last_pw_change": "Остання зміна пароля", + "last_run": "Останній запуск", + "loading": "Завантаження...", + "login_history": "Історія входу до системи", + "mailbox": "Поштова скринька", + "mailbox_details": "Деталі", + "mailbox_general": "Основні", + "mailbox_settings": "Налаштування", + "messages": "листів", + "month": "місяць", + "never": "Ніколи", + "new_password": "Новий пароль", + "no_active_filter": "Активні фільтри відсутні", + "no_last_login": "Інформація про останній вхід до інтерфейсу користувача відсутня", + "no_record": "Записи відсутні", + "open_logs": "Показати журнал", + "password": "Пароль", + "password_now": "Поточний пароль (підтвердіть зміни)", + "password_repeat": "Підтвердження пароля (повтор)", + "pushover_only_x_prio": "Отримувати повідомлення лише про листи з високим пріоритетом [X-Priority: 1]", + "pushover_sender_array": "Отримувати повідомлення від списку адрес електронної пошти (розділені комами)", + "pushover_sender_regex": "Отримувати сповіщення від відправників, що задовольняють regex-вираженню:", + "pushover_text": "Текст сповіщення", + "pushover_verify": "Перевірити доступ", + "q_add_header": "Небажана пошта", + "q_all": "Всі категорії", + "quarantine_notification": "Сповіщення про спам", + "quarantine_notification_info": "Щойно сповіщення буде надіслано, елементи будуть позначені як \"сповіщені\", і для цього повідомлення більше не надсилатимуться сповіщення.", + "recent_successful_connections": "Історія успішних підключень", + "remove": "Видалити", + "running": "В процесі", + "save": "Зберегти зміни", + "save_changes": "Зберегти зміни", + "shared_aliases": "Загальні псевдоніми", + "show_sieve_filters": "Показати увімкнені фільтри sieve", + "sogo_profile_reset": "Скинути профіль SOGo", + "sogo_profile_reset_help": "Увага: це видалить налаштування профілю SOGo разом з усі контактами, календарями та фільтрами безповоротно.", + "sogo_profile_reset_now": "Скинути профіль зараз", + "spam_score_reset": "Скинути на налаштування за замовчуванням", + "spamfilter": "Спам-фільтр", + "spamfilter_bl": "Чорний список", + "spamfilter_default_score": "Значення за замовчуванням", + "spamfilter_green": "Зелений: ці листи не є спамом", + "spamfilter_hint": "Перше значення описує \"низький показник спаму\", друге – \"високий показник спаму\".", + "spamfilter_red": "Червоний: ці листи є спамом та будуть відхилені сервером", + "spamfilter_table_action": "Дії", + "spamfilter_table_add": "Додати елемент", + "spamfilter_table_domain_policy": "n/a (політика домену)", + "spamfilter_table_empty": "Пусто", + "spamfilter_table_remove": "видалити", + "spamfilter_table_rule": "Правило", + "spamfilter_wl": "Білий список", + "spamfilter_yellow": "Жовтий: ці листи можуть бути спамом, будуть доставлені до папки \"Спам\"", + "status": "Статус", + "sync_jobs": "Завдання синхронізації", + "syncjob_check_log": "Перевірити журнал", + "syncjob_last_run_result": "Результат", + "syncjob_EX_OK": "Успішно", + "syncjob_EXIT_CONNECTION_FAILURE": "Помилка зв'язку із сервером", + "syncjob_EXIT_AUTHENTICATION_FAILURE": "Проблема аутентифікації", + "syncjob_EXIT_OVERQUOTA": "Цільова поштова скринька перевищила квоту", + "syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Не вдалося підключитися до віддаленого сервера", + "tag_handling": "Обробка тегованої пошти", + "tag_help_example": "Приклад тегованої адреси електронної пошти: me+Facebook@example.org", + "tag_in_none": "Нічого не робити", + "tag_in_subfolder": "Перемістити в підпапку", + "tag_in_subject": "Додати до теми листа", + "text": "Текст", + "title": "Заголовок", + "tls_enforce_in": "Примусовий TLS (вхідні)", + "tls_enforce_out": "Примусовий TLS (вихідні)", + "tls_policy": "Політика шифрування", + "user_settings": "Налаштування користувача", + "username": "Ім'я користувача", + "verify": "Перевірити", + "waiting": "В очікуванні", + "week": "тиждень", + "weekly": "Раз на тиждень", + "weeks": "тижні", + "with_app_password": "з паролем додатка", + "alias_remove_all": "Видалити всі псевдоніми", + "aliases_send_as_all": "Дозволено надсилати листи від будь-якого імені для домену та його псевдонімів", + "app_hint": "Паролі додатків - це альтернативні паролі для авторизації в IMAP, SMTP, CalDAV, CardDAV та EAS. При цьому, ім'я користувача залишається незмінним. SOGo недоступний через паролі додатків.", + "apple_connection_profile_with_app_password": "Новий пароль додатка генерується та додається до профілю, тому не потрібно вводити пароль під час налаштування пристрою. Не надавайте доступ до файлу, оскільки він надає повний доступ до вашої поштової скриньки.", + "client_configuration": "Показати посібники з налаштування поштових клієнтів та смартфонів", + "direct_aliases": "Особисті псевдоніми", + "direct_aliases_desc": "На особисті псевдоніми розповсюджуються фільтри небажаної пошти та параметри політики TLS.", + "direct_protocol_access": "Цей користувач поштової скриньки має прямий, зовнішній доступ до наведених нижче протоколів і програм. Цими параметрами керує ваш адміністратор. Паролі додатків можна створювати для надання доступу до окремих протоколів і програм.
Кнопка \"Увійти до веб-пошти\" забезпечує єдиний вхід в SOGo і завжди доступна.", + "force_pw_update": "Ви повинні встановити новий пароль для доступу до сервісів, що належать до цього облікового запису.", + "is_catch_all": "Catch-all для домена/ів", + "last_ui_login": "Останній вхід до особистого кабінету", + "months": "місяців", + "new_password_repeat": "Підтвердження пароля (повтор)", + "open_webmail_sso": "Вхід до веб-пошти", + "pushover_evaluate_x_prio": "Встановити високий пріоритет повідомлень для листів із високим пріоритетом [X-Priority: 1]", + "pushover_info": "Налаштування Push-повідомлень будуть застосовуватися до всієї пошти %s (за винятком спаму), включаючи псевдоніми (особисті, загальні та теговані).", + "pushover_title": "Заголовок сповіщення", + "pushover_vars": "Коли фільтрація по відправнику не визначена, повідомлення будуть доставлятися від усіх відправників.
Можна використовувати звичайний фільтр по відправнику та розширений regex-фільтр, а також обидва відразу.
Придатні для використання змінні для тексту та заголовка (будь ласка, зверніть увагу на політику захисту даних)", + "q_reject": "Відхилена пошта", + "quarantine_category": "Категорія сповіщень про спам", + "quarantine_category_info": "Категорія \"Відхилена пошта\" включає пошту, яка була відхилена, тоді як \"Небажана пошта\" містить листи, які були поміщені в папку Спам. Щоб отримувати сповіщення про всі категорії спаму, виберіть \"Всі категорії\".", + "sender_acl_disabled": "Перевірку відправника вимкнено", + "shared_aliases_desc": "На загальні псевдоніми не впливають налаштування користувача, такі як фільтр небажаної пошти, або політика шифрування. Відповідні фільтри небажаної пошти можуть бути створені лише адміністратором у рамках політики домену.", + "spam_aliases": "Тимчасові псевдоніми електронної пошти", + "spamfilter_behavior": "Фільтрування спаму", + "spamfilter_bl_desc": "Всі листи, отримані від адрес електронної пошти, доданих до чорного списку, будуть відхилені та не будуть скопійовані до карантину. Використання * дозволено. Фільтр застосовується тільки до особистих псевдонімів (з одним одержувачем), за винятком catch-all псевдонімів та самого поштового облікового запису.", + "spamfilter_wl_desc": "Адреси електронної пошти з білого списку запрограмовані так, щоб ніколи не класифікуватися як спам. Можна використовувати символи підстановки (*). Фільтр застосовується лише до прямих псевдонімів (псевдонімів з однією цільовою поштовою скринькою), за винятком псевдонімів загального доступу та самої поштової скриньки.", + "syncjob_EXIT_TLS_FAILURE": "Помилка встановлення шифрованого з'єднання", + "syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Неправильне ім'я користувача або пароль", + "tag_help_explain": "Перемістити до підпапки: буде створено нову підпапку в INBOX з ім'ям тега, наприклад: \"INBOX/Facebook\".
\n Додати до теми листа: ім'я тега буде додано до теми листа, наприклад: \"[Facebook] My News\".", + "tls_policy_warning": "Попередження: якщо ви увімкнете примусове шифрування пошти, ви можете зіткнутися з втратою листів.
Повідомлення, які не відповідають політиці, будуть відкидатися з повідомленням поштовим сервером про серйозний збій.
Цей параметр застосовується до вашої основної адреси електронної пошти (логіну), усім особистим псевдонімам та псевдонімам доменів. Маються на увазі лише псевдоніми з однією поштовою скринькою, як одержувач.", + "year": "рік", + "years": "років" + }, + "warning": { + "domain_added_sogo_failed": "Домен був доданий, але перезавантажити SOGo не вдалося, будь ласка, перевірте журнали сервера.", + "dovecot_restart_failed": "Перезавантаження Dovecot не вдалося, будь ласка, перевірте журнали сервера.", + "fuzzy_learn_error": "Помилка збереження нечіткого хеша: %s", + "no_active_admin": "Неможливо деактивувати останнього активного адміністратора", + "quota_exceeded_scope": "Квоту домену перевищено: можуть бути створені лише поштові скриньки без обмеження.", + "session_token": "Неправильний токен форми: невідповідність токена", + "session_ua": "Невірний токен форми: помилка перевірки User-Agent", + "cannot_delete_self": "Неможливо видалити користувача, який увійшов у систему", + "hash_not_found": "Хеш не знайдено або вже видалено", + "ip_invalid": "Пропущено недійсний IP: %s", + "is_not_primary_alias": "Пропущено неосновний псевдонім %s" + } +} From 998cb642a9481462ad4f524c164324b1c2c4a215 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 19 May 2022 10:43:06 +0200 Subject: [PATCH 02/52] [UI] Moved Password Change warning to top for user site --- data/web/templates/user/tab-user-auth.twig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/web/templates/user/tab-user-auth.twig b/data/web/templates/user/tab-user-auth.twig index e1f84fff..301f8443 100644 --- a/data/web/templates/user/tab-user-auth.twig +++ b/data/web/templates/user/tab-user-auth.twig @@ -2,11 +2,14 @@
{{ lang.user.mailbox_general }}
+ {% if mailboxdata.attributes.force_pw_update == '1' %} +
{{ lang.user.force_pw_update|raw }}
+ {% endif %} {% if not skip_sogo %}
- {% if dual_login and allow_admin_email_login == 'n' %} + {% if dual_login and allow_admin_email_login == 'n' or mailboxdata.attributes.force_pw_update == '1' %} @@ -115,9 +118,6 @@
- {% if mailboxdata.attributes.force_pw_update == '1' %} -
{{ lang.user.force_pw_update|raw }}
- {% endif %}

[{{ lang.user.client_configuration }}]

[{{ lang.user.show_sieve_filters }}]


From 33e5ad2b5c43140529a83580f88c850d051debd7 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 19 May 2022 14:41:21 +0200 Subject: [PATCH 03/52] [Imapsync] Case sensitive PIPEMESS removal --- data/web/inc/functions.mailbox.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 1c6e5b40..88ee1ca6 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -337,7 +337,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $enc1 = $_data['enc1']; $custom_params = (empty(trim($_data['custom_params']))) ? '' : trim($_data['custom_params']); // Workaround, fixme - if (strpos($custom_params, 'pipemess')) { + if (stripos($custom_params, 'pipemess')) { $custom_params = ''; } if (empty($subfolder2)) { @@ -1746,7 +1746,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ); continue; } - if (strpos($custom_params, 'pipemess')) { + if (stripos($custom_params, 'pipemess')) { $custom_params = ''; } if (empty($subfolder2)) { From 8d9102aa088c780ca2f1cc0f39b224d735dc8569 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 19 May 2022 14:41:21 +0200 Subject: [PATCH 04/52] [Imapsync] Case sensitive PIPEMESS removal (cherry picked from commit 33e5ad2b5c43140529a83580f88c850d051debd7) --- data/web/inc/functions.mailbox.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 1c6e5b40..88ee1ca6 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -337,7 +337,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $enc1 = $_data['enc1']; $custom_params = (empty(trim($_data['custom_params']))) ? '' : trim($_data['custom_params']); // Workaround, fixme - if (strpos($custom_params, 'pipemess')) { + if (stripos($custom_params, 'pipemess')) { $custom_params = ''; } if (empty($subfolder2)) { @@ -1746,7 +1746,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ); continue; } - if (strpos($custom_params, 'pipemess')) { + if (stripos($custom_params, 'pipemess')) { $custom_params = ''; } if (empty($subfolder2)) { From 97df5c3b9c3b856aa08a88ea7c6a961dc749ace2 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 19 May 2022 15:42:13 +0200 Subject: [PATCH 05/52] [DB] Update DB Version to remove pipemess parameters --- data/web/inc/init_db.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index 225e2baf..8b0a9750 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 = "02052022_1500"; + $db_version = "19052022_1541"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); From 552f09f48aacda3a14238101c8a0f4c922ffe65f Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 19 May 2022 15:42:13 +0200 Subject: [PATCH 06/52] [DB] Update DB Version to remove pipemess parameters (cherry picked from commit 97df5c3b9c3b856aa08a88ea7c6a961dc749ace2) --- data/web/inc/init_db.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index 225e2baf..8b0a9750 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 = "02052022_1500"; + $db_version = "19052022_1541"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); From 05b86090737959222736dc540823cb4cc37c45f2 Mon Sep 17 00:00:00 2001 From: Niklas Meyer Date: Thu, 19 May 2022 18:49:01 +0200 Subject: [PATCH 07/52] [Postfix] Update to 3.5.6 (Rebase to Debian 11) --- data/Dockerfiles/postfix/Dockerfile | 2 +- data/Dockerfiles/postfix/syslog-ng-redis_slave.conf | 2 +- data/Dockerfiles/postfix/syslog-ng.conf | 2 +- docker-compose.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/Dockerfiles/postfix/Dockerfile b/data/Dockerfiles/postfix/Dockerfile index 56b274aa..e3c64987 100644 --- a/data/Dockerfiles/postfix/Dockerfile +++ b/data/Dockerfiles/postfix/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:buster-slim +FROM debian:bullseye-slim LABEL maintainer "Andre Peters " ARG DEBIAN_FRONTEND=noninteractive diff --git a/data/Dockerfiles/postfix/syslog-ng-redis_slave.conf b/data/Dockerfiles/postfix/syslog-ng-redis_slave.conf index 40fb1cda..558305ec 100644 --- a/data/Dockerfiles/postfix/syslog-ng-redis_slave.conf +++ b/data/Dockerfiles/postfix/syslog-ng-redis_slave.conf @@ -1,4 +1,4 @@ -@version: 3.19 +@version: 3.28 @include "scl.conf" options { chain_hostnames(off); diff --git a/data/Dockerfiles/postfix/syslog-ng.conf b/data/Dockerfiles/postfix/syslog-ng.conf index 8fdc104e..a1ccd07e 100644 --- a/data/Dockerfiles/postfix/syslog-ng.conf +++ b/data/Dockerfiles/postfix/syslog-ng.conf @@ -1,4 +1,4 @@ -@version: 3.19 +@version: 3.28 @include "scl.conf" options { chain_hostnames(off); diff --git a/docker-compose.yml b/docker-compose.yml index 549c2cac..3a5f198d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -293,7 +293,7 @@ services: - dovecot postfix-mailcow: - image: mailcow/postfix:1.66 + image: mailcow/postfix:1.67 depends_on: - mysql-mailcow volumes: From b1658c0f83712e72bd313a99a625298dd39c90d7 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Fri, 20 May 2022 09:30:42 +0200 Subject: [PATCH 08/52] [IMAPSYNC] Hardened pipemess exploit prevention (pipemes) --- data/web/inc/functions.mailbox.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 88ee1ca6..623f6c38 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -337,7 +337,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $enc1 = $_data['enc1']; $custom_params = (empty(trim($_data['custom_params']))) ? '' : trim($_data['custom_params']); // Workaround, fixme - if (stripos($custom_params, 'pipemess')) { + if (stripos($custom_params, 'pipemess') || stripos($custom_params, 'pipemes')) { $custom_params = ''; } if (empty($subfolder2)) { @@ -1746,7 +1746,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ); continue; } - if (stripos($custom_params, 'pipemess')) { + if (stripos($custom_params, 'pipemess') || stripos($custom_params, 'pipemes')) { $custom_params = ''; } if (empty($subfolder2)) { From c27ad97287a73e2a2bfe1b17cce920919910a0ee Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Fri, 20 May 2022 09:44:11 +0200 Subject: [PATCH 09/52] [DB] Remove pipemes from custom_params --- data/web/inc/init_db.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index 8b0a9750..88be5bca 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 = "19052022_1541"; + $db_version = "20052022_0938"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -1228,7 +1228,7 @@ function init_db_schema() { } // Mitigate imapsync pipemess issue - $pdo->query("UPDATE `imapsync` SET `custom_params` = '' WHERE `custom_params` LIKE '%pipemess%';"); + $pdo->query("UPDATE `imapsync` SET `custom_params` = '' WHERE `custom_params` LIKE '%pipemess%' OR `custom_params` LIKE '%pipemes%';"); // Migrate webauthn tfa $stmt = $pdo->query("ALTER TABLE `tfa` MODIFY COLUMN `authmech` ENUM('yubi_otp', 'u2f', 'hotp', 'totp', 'webauthn')"); From d06119a21d4df50ffc0b591d04e76f67118f91ee Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Fri, 20 May 2022 09:30:42 +0200 Subject: [PATCH 10/52] [IMAPSYNC] Hardened pipemess exploit prevention (pipemes) (cherry picked from commit b1658c0f83712e72bd313a99a625298dd39c90d7) --- data/web/inc/functions.mailbox.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 88ee1ca6..623f6c38 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -337,7 +337,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $enc1 = $_data['enc1']; $custom_params = (empty(trim($_data['custom_params']))) ? '' : trim($_data['custom_params']); // Workaround, fixme - if (stripos($custom_params, 'pipemess')) { + if (stripos($custom_params, 'pipemess') || stripos($custom_params, 'pipemes')) { $custom_params = ''; } if (empty($subfolder2)) { @@ -1746,7 +1746,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ); continue; } - if (stripos($custom_params, 'pipemess')) { + if (stripos($custom_params, 'pipemess') || stripos($custom_params, 'pipemes')) { $custom_params = ''; } if (empty($subfolder2)) { From 040206859f5b8e2483841bd9da793ad7df49de84 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Fri, 20 May 2022 09:44:11 +0200 Subject: [PATCH 11/52] [DB] Remove pipemes from custom_params (cherry picked from commit c27ad97287a73e2a2bfe1b17cce920919910a0ee) --- data/web/inc/init_db.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index 8b0a9750..88be5bca 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 = "19052022_1541"; + $db_version = "20052022_0938"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -1228,7 +1228,7 @@ function init_db_schema() { } // Mitigate imapsync pipemess issue - $pdo->query("UPDATE `imapsync` SET `custom_params` = '' WHERE `custom_params` LIKE '%pipemess%';"); + $pdo->query("UPDATE `imapsync` SET `custom_params` = '' WHERE `custom_params` LIKE '%pipemess%' OR `custom_params` LIKE '%pipemes%';"); // Migrate webauthn tfa $stmt = $pdo->query("ALTER TABLE `tfa` MODIFY COLUMN `authmech` ENUM('yubi_otp', 'u2f', 'hotp', 'totp', 'webauthn')"); From 4d53216c05ff91884d2005d367af4d00ec98126b Mon Sep 17 00:00:00 2001 From: qupfer Date: Tue, 31 May 2022 09:34:06 +0200 Subject: [PATCH 12/52] [Compose] Remove bind options from volumes (#4577) --- docker-compose.yml | 48 +++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 549c2cac..711f3c05 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,8 +22,8 @@ services: - unbound-mailcow stop_grace_period: 45s volumes: - - mysql-vol-1:/var/lib/mysql/:Z - - mysql-socket-vol-1:/var/run/mysqld/:z + - mysql-vol-1:/var/lib/mysql/ + - mysql-socket-vol-1:/var/run/mysqld/ - ./data/conf/mysql/:/etc/mysql/conf.d/:ro,Z environment: - TZ=${TZ} @@ -43,7 +43,7 @@ services: redis-mailcow: image: redis:6-alpine volumes: - - redis-vol-1:/data/:Z + - redis-vol-1:/data/ restart: always ports: - "${REDIS_PORT:-127.0.0.1:7654}:6379" @@ -67,7 +67,7 @@ services: - SKIP_CLAMD=${SKIP_CLAMD:-n} volumes: - ./data/conf/clamav/:/etc/clamav/:Z - - clamd-db-vol-1:/var/lib/clamav:z + - clamd-db-vol-1:/var/lib/clamav networks: mailcow-network: aliases: @@ -113,8 +113,8 @@ services: - ./data/web:/web:z - ./data/conf/rspamd/dynmaps:/dynmaps:ro,z - ./data/conf/rspamd/custom/:/rspamd_custom_maps:z - - rspamd-vol-1:/var/lib/rspamd:z - - mysql-socket-vol-1:/var/run/mysqld/:z + - rspamd-vol-1:/var/lib/rspamd + - mysql-socket-vol-1:/var/run/mysqld/ - ./data/conf/sogo/:/etc/sogo/:z - ./data/conf/rspamd/meta_exporter:/meta_exporter:ro,z - ./data/conf/phpfpm/sogo-sso/:/etc/sogo-sso/:z @@ -192,9 +192,9 @@ services: - ./data/conf/sogo/custom-favicon.ico:/usr/lib/GNUstep/SOGo/WebServerResources/img/sogo.ico:z - ./data/conf/sogo/custom-theme.js:/usr/lib/GNUstep/SOGo/WebServerResources/js/theme.js:z - ./data/conf/sogo/custom-sogo.js:/usr/lib/GNUstep/SOGo/WebServerResources/js/custom-sogo.js:z - - mysql-socket-vol-1:/var/run/mysqld/:z - - sogo-web-vol-1:/sogo_web:z - - sogo-userdata-backup-vol-1:/sogo_backup:Z + - mysql-socket-vol-1:/var/run/mysqld/ + - sogo-web-vol-1:/sogo_web + - sogo-userdata-backup-vol-1:/sogo_backup labels: ofelia.enabled: "true" ofelia.job-exec.sogo_sessions.schedule: "@every 1m" @@ -226,13 +226,13 @@ services: - ./data/assets/ssl:/etc/ssl/mail/:ro,z - ./data/conf/sogo/:/etc/sogo/:z - ./data/conf/phpfpm/sogo-sso/:/etc/phpfpm/:z - - vmail-vol-1:/var/vmail:Z - - vmail-index-vol-1:/var/vmail_index:Z - - crypt-vol-1:/mail_crypt/:z + - vmail-vol-1:/var/vmail + - vmail-index-vol-1:/var/vmail_index + - crypt-vol-1:/mail_crypt/ - ./data/conf/rspamd/custom/:/etc/rspamd/custom:z - ./data/assets/templates:/templates:z - - rspamd-vol-1:/var/lib/rspamd:z - - mysql-socket-vol-1:/var/run/mysqld/:z + - rspamd-vol-1:/var/lib/rspamd + - mysql-socket-vol-1:/var/run/mysqld/ environment: - DOVECOT_MASTER_USER=${DOVECOT_MASTER_USER:-} - DOVECOT_MASTER_PASS=${DOVECOT_MASTER_PASS:-} @@ -300,10 +300,10 @@ services: - ./data/hooks/postfix:/hooks:Z - ./data/conf/postfix:/opt/postfix/conf:z - ./data/assets/ssl:/etc/ssl/mail/:ro,z - - postfix-vol-1:/var/spool/postfix:z - - crypt-vol-1:/var/lib/zeyple:z - - rspamd-vol-1:/var/lib/rspamd:z - - mysql-socket-vol-1:/var/run/mysqld/:z + - postfix-vol-1:/var/spool/postfix + - crypt-vol-1:/var/lib/zeyple + - rspamd-vol-1:/var/lib/rspamd + - mysql-socket-vol-1:/var/run/mysqld/ environment: - LOG_LINES=${LOG_LINES:-9999} - TZ=${TZ} @@ -373,7 +373,7 @@ services: - ./data/assets/ssl/:/etc/ssl/mail/:ro,z - ./data/conf/nginx/:/etc/nginx/conf.d/:z - ./data/conf/rspamd/meta_exporter:/meta_exporter:ro,z - - sogo-web-vol-1:/usr/lib/GNUstep/SOGo/:z + - sogo-web-vol-1:/usr/lib/GNUstep/SOGo/ ports: - "${HTTPS_BIND:-:}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}" - "${HTTP_BIND:-:}:${HTTP_PORT:-80}:${HTTP_PORT:-80}" @@ -414,7 +414,7 @@ services: - ./data/web/.well-known/acme-challenge:/var/www/acme:z - ./data/assets/ssl:/var/lib/acme/:z - ./data/assets/ssl-example:/var/lib/ssl-example/:ro,Z - - mysql-socket-vol-1:/var/run/mysqld/:z + - mysql-socket-vol-1:/var/run/mysqld/ restart: always networks: mailcow-network: @@ -451,9 +451,9 @@ services: tmpfs: - /tmp volumes: - - rspamd-vol-1:/var/lib/rspamd:z - - mysql-socket-vol-1:/var/run/mysqld/:z - - postfix-vol-1:/var/spool/postfix:z + - rspamd-vol-1:/var/lib/rspamd + - mysql-socket-vol-1:/var/run/mysqld/ + - postfix-vol-1:/var/spool/postfix - ./data/assets/ssl:/etc/ssl/mail/:ro,z restart: always environment: @@ -528,7 +528,7 @@ services: image: mailcow/solr:1.8.1 restart: always volumes: - - solr-vol-1:/opt/solr/server/solr/dovecot-fts/data:Z + - solr-vol-1:/opt/solr/server/solr/dovecot-fts/data ports: - "${SOLR_PORT:-127.0.0.1:18983}:8983" environment: From 4390c9855a494164adde28ebff713991af19e841 Mon Sep 17 00:00:00 2001 From: milkmaker Date: Tue, 31 May 2022 19:59:00 +0200 Subject: [PATCH 13/52] [Web] Updated lang.de.json [CI SKIP] (#4600) [Web] Updated lang.de.json [CI SKIP] Co-authored-by: Peter Co-authored-by: milkmaker Co-authored-by: Peter --- data/web/lang/lang.de.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/web/lang/lang.de.json b/data/web/lang/lang.de.json index 02458885..44dc8285 100644 --- a/data/web/lang/lang.de.json +++ b/data/web/lang/lang.de.json @@ -106,7 +106,8 @@ "timeout2": "Timeout für Verbindung zum lokalen Host", "username": "Benutzername", "validate": "Validieren", - "validation_success": "Erfolgreich validiert" + "validation_success": "Erfolgreich validiert", + "tags": "Tags" }, "admin": { "access": "Zugang", From 1edd4012e4d3f0ab9456d5750e7be19ee55ee1f5 Mon Sep 17 00:00:00 2001 From: Niklas Meyer <62480600+DerLinkman@users.noreply.github.com> Date: Fri, 3 Jun 2022 14:37:56 +0200 Subject: [PATCH 14/52] [Web] escapehtml in mailbox.js (#4604) Co-authored-by: FreddleSpl0it --- data/web/js/site/mailbox.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js index d03dec77..dedbe454 100644 --- a/data/web/js/site/mailbox.js +++ b/data/web/js/site/mailbox.js @@ -553,6 +553,7 @@ jQuery(function($){ '
'; item.chkbox = ''; item.name = escapeHtml(item.name); + item.description = escapeHtml(item.description); }); } }), @@ -1022,7 +1023,7 @@ jQuery(function($){ if (!item.exclude > 0) { item.exclude = '-'; } else { - item.exclude = '' + item.exclude + ''; + item.exclude = '' + escapeHtml(item.exclude) + ''; } item.server_w_port = escapeHtml(item.user1) + '@' + item.host1 + ':' + item.port1; item.action = '
' + From d13be25f45821883108a4bf4b33ec4674857108f Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 5 Jun 2022 18:38:16 +0200 Subject: [PATCH 15/52] Update base image to alpine 3.16 --- data/Dockerfiles/netfilter/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/Dockerfiles/netfilter/Dockerfile b/data/Dockerfiles/netfilter/Dockerfile index ce8fddbc..621da149 100644 --- a/data/Dockerfiles/netfilter/Dockerfile +++ b/data/Dockerfiles/netfilter/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.15 +FROM alpine:3.16 LABEL maintainer "Andre Peters " ENV XTABLES_LIBDIR /usr/lib/xtables From 2bd436dfd836f6edbf06c14c9d1b60e817b0d1f5 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 5 Jun 2022 18:41:54 +0200 Subject: [PATCH 16/52] Update base image to alpine 3.16 --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 8606eb35..9b64185c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -422,7 +422,7 @@ services: - acme netfilter-mailcow: - image: mailcow/netfilter:1.47 + image: mailcow/netfilter:1.48 stop_grace_period: 30s depends_on: - dovecot-mailcow From 1db5841424f9b04efe48d711ed65c56f37ae6166 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 5 Jun 2022 18:59:56 +0200 Subject: [PATCH 17/52] Update base image to alpine 3.16 --- data/Dockerfiles/watchdog/Dockerfile | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/Dockerfiles/watchdog/Dockerfile b/data/Dockerfiles/watchdog/Dockerfile index 4f599c45..637c4680 100644 --- a/data/Dockerfiles/watchdog/Dockerfile +++ b/data/Dockerfiles/watchdog/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.15 +FROM alpine:3.16 LABEL maintainer "André Peters " # Installation diff --git a/docker-compose.yml b/docker-compose.yml index 9b64185c..cb36383f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -445,7 +445,7 @@ services: - /lib/modules:/lib/modules:ro watchdog-mailcow: - image: mailcow/watchdog:1.96 + image: mailcow/watchdog:1.97 dns: - ${IPV4_NETWORK:-172.22.1}.254 tmpfs: From c41dc9d8c0ec66c53d0bc812705b602a506ff8ca Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 5 Jun 2022 19:01:06 +0200 Subject: [PATCH 18/52] Update base image to alpine 3.16 --- data/Dockerfiles/unbound/Dockerfile | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/Dockerfiles/unbound/Dockerfile b/data/Dockerfiles/unbound/Dockerfile index 54387a6e..0b1cefe9 100644 --- a/data/Dockerfiles/unbound/Dockerfile +++ b/data/Dockerfiles/unbound/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.15 +FROM alpine:3.16 LABEL maintainer "Andre Peters " diff --git a/docker-compose.yml b/docker-compose.yml index 9b64185c..f0b333d2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '2.1' services: unbound-mailcow: - image: mailcow/unbound:1.15 + image: mailcow/unbound:1.16 environment: - TZ=${TZ} volumes: From c9dbc7c7b780b4caab7e9c88a8bc8ebdecaa19a2 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 5 Jun 2022 19:01:55 +0200 Subject: [PATCH 19/52] Update base image to alpine 3.16 --- data/Dockerfiles/acme/Dockerfile | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/Dockerfiles/acme/Dockerfile b/data/Dockerfiles/acme/Dockerfile index a0ec058c..f5b7b56c 100644 --- a/data/Dockerfiles/acme/Dockerfile +++ b/data/Dockerfiles/acme/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.15 +FROM alpine:3.16 LABEL maintainer "Andre Peters " diff --git a/docker-compose.yml b/docker-compose.yml index 9b64185c..3133685e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -386,7 +386,7 @@ services: acme-mailcow: depends_on: - nginx-mailcow - image: mailcow/acme:1.81 + image: mailcow/acme:1.82 dns: - ${IPV4_NETWORK:-172.22.1}.254 environment: From 1c479684fc313511d8533c0dd2d79d1c1db6a427 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 5 Jun 2022 19:02:21 +0200 Subject: [PATCH 20/52] Revert "Update base image to alpine 3.16" This reverts commit c9dbc7c7b780b4caab7e9c88a8bc8ebdecaa19a2. --- data/Dockerfiles/acme/Dockerfile | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/Dockerfiles/acme/Dockerfile b/data/Dockerfiles/acme/Dockerfile index f5b7b56c..a0ec058c 100644 --- a/data/Dockerfiles/acme/Dockerfile +++ b/data/Dockerfiles/acme/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.16 +FROM alpine:3.15 LABEL maintainer "Andre Peters " diff --git a/docker-compose.yml b/docker-compose.yml index 3133685e..9b64185c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -386,7 +386,7 @@ services: acme-mailcow: depends_on: - nginx-mailcow - image: mailcow/acme:1.82 + image: mailcow/acme:1.81 dns: - ${IPV4_NETWORK:-172.22.1}.254 environment: From a21b3cd606d34e3aff35ce259ba564de3474c979 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 5 Jun 2022 19:03:37 +0200 Subject: [PATCH 21/52] Update base image to alpine 3.16 --- data/Dockerfiles/acme/Dockerfile | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/Dockerfiles/acme/Dockerfile b/data/Dockerfiles/acme/Dockerfile index a0ec058c..f5b7b56c 100644 --- a/data/Dockerfiles/acme/Dockerfile +++ b/data/Dockerfiles/acme/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.15 +FROM alpine:3.16 LABEL maintainer "Andre Peters " diff --git a/docker-compose.yml b/docker-compose.yml index 9b64185c..3133685e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -386,7 +386,7 @@ services: acme-mailcow: depends_on: - nginx-mailcow - image: mailcow/acme:1.81 + image: mailcow/acme:1.82 dns: - ${IPV4_NETWORK:-172.22.1}.254 environment: From 0bc2a16093d80c74bd6a4eec8511e770cfba5aaa Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 5 Jun 2022 19:04:51 +0200 Subject: [PATCH 22/52] Update base image to alpine 3.16 --- data/Dockerfiles/dockerapi/Dockerfile | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/Dockerfiles/dockerapi/Dockerfile b/data/Dockerfiles/dockerapi/Dockerfile index fb51f079..41d4a78f 100644 --- a/data/Dockerfiles/dockerapi/Dockerfile +++ b/data/Dockerfiles/dockerapi/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.15 +FROM alpine:3.16 LABEL maintainer "Andre Peters " diff --git a/docker-compose.yml b/docker-compose.yml index 9b64185c..e35f3e33 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -507,7 +507,7 @@ services: - watchdog dockerapi-mailcow: - image: mailcow/dockerapi:1.41 + image: mailcow/dockerapi:1.42 security_opt: - label=disable restart: always From cd1715ba52111c6b67e739df1a609405ac9f4b2b Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 5 Jun 2022 19:06:03 +0200 Subject: [PATCH 23/52] Update base image to alpine 3.16 --- data/Dockerfiles/olefy/Dockerfile | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/Dockerfiles/olefy/Dockerfile b/data/Dockerfiles/olefy/Dockerfile index a1a42482..889f84b4 100644 --- a/data/Dockerfiles/olefy/Dockerfile +++ b/data/Dockerfiles/olefy/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.15 +FROM alpine:3.16 LABEL maintainer "Andre Peters " WORKDIR /app diff --git a/docker-compose.yml b/docker-compose.yml index 9b64185c..31ad6eaa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -541,7 +541,7 @@ services: - solr olefy-mailcow: - image: mailcow/olefy:1.9 + image: mailcow/olefy:1.10 restart: always environment: - TZ=${TZ} From 2229f87d9b93ea91dc369eba9752a678b518299f Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 5 Jun 2022 19:36:09 +0200 Subject: [PATCH 24/52] Update base image to alpine 3.16 and updated some dependencies --- data/Dockerfiles/phpfpm/Dockerfile | 10 +++++----- docker-compose.yml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/data/Dockerfiles/phpfpm/Dockerfile b/data/Dockerfiles/phpfpm/Dockerfile index ca851e65..74035c02 100644 --- a/data/Dockerfiles/phpfpm/Dockerfile +++ b/data/Dockerfiles/phpfpm/Dockerfile @@ -1,12 +1,12 @@ -FROM php:8.0-fpm-alpine3.14 +FROM php:8.0-fpm-alpine3.16 LABEL maintainer "Andre Peters " -ENV APCU_PECL 5.1.20 -ENV IMAGICK_PECL 3.5.1 +ENV APCU_PECL 5.1.21 +ENV IMAGICK_PECL 3.7.0 # Mailparse is pulled from master branch #ENV MAILPARSE_PECL 3.0.2 -ENV MEMCACHED_PECL 3.1.5 -ENV REDIS_PECL 5.3.4 +ENV MEMCACHED_PECL 3.2.0 +ENV REDIS_PECL 5.3.7 RUN apk add -U --no-cache autoconf \ aspell-dev \ diff --git a/docker-compose.yml b/docker-compose.yml index c5c156d6..17fd58f1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -104,7 +104,7 @@ services: - rspamd php-fpm-mailcow: - image: mailcow/phpfpm:1.78 + image: mailcow/phpfpm:1.79 command: "php-fpm -d date.timezone=${TZ} -d expose_php=0" depends_on: - redis-mailcow From 714511b0a84691f4c52f55ebbe982623f2512c80 Mon Sep 17 00:00:00 2001 From: Niklas Meyer <62480600+DerLinkman@users.noreply.github.com> Date: Tue, 7 Jun 2022 08:53:08 +0200 Subject: [PATCH 25/52] [Compose] Update to Docker Compose v2 (#4605) * Change default HTTP_BIND, HTTPS_BIND https://github.com/mailcow/mailcow-dockerized/issues/4315#issuecomment-1083034329 * [Compose] Removed Colon after fallback IP in docker-compose.yml * [Compose] Remove bind options from volumes (#4577) (cherry picked from commit 4d53216c05ff91884d2005d367af4d00ec98126b) * Migration (partially) of update.sh + cold-standby.sh to composev2 * Migration of update.sh + cold-standby.sh to composev2 * Migration of update.sh + cold-standby.sh to composev2 * Migration of update.sh + cold-standby.sh to composev2 * [ClamAV] Fixed ClamAV start before unbound * Migration of update.sh + cold-standby.sh to composev2 * Formulation and values adjusted (IPv4 bind in generate-config.sh) Co-authored-by: Amin Vakil Co-authored-by: qupfer Co-authored-by: FreddleSpl0it --- docker-compose.yml | 6 +- generate_config.sh | 23 ++++++- helper-scripts/_cold-standby.sh | 70 ++++++++++++++++++---- helper-scripts/backup_and_restore.sh | 29 ++++++++- update.sh | 89 +++++++++++----------------- 5 files changed, 145 insertions(+), 72 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 17fd58f1..77b9c3cf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -60,6 +60,8 @@ services: clamd-mailcow: image: mailcow/clamd:1.52 restart: always + depends_on: + - unbound-mailcow dns: - ${IPV4_NETWORK:-172.22.1}.254 environment: @@ -375,8 +377,8 @@ services: - ./data/conf/rspamd/meta_exporter:/meta_exporter:ro,z - sogo-web-vol-1:/usr/lib/GNUstep/SOGo/ ports: - - "${HTTPS_BIND:-:}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}" - - "${HTTP_BIND:-:}:${HTTP_PORT:-80}:${HTTP_PORT:-80}" + - "${HTTPS_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}" + - "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:${HTTP_PORT:-80}" restart: always networks: mailcow-network: diff --git a/generate_config.sh b/generate_config.sh index f2f444c5..45cfaf56 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -25,10 +25,29 @@ if cp --help 2>&1 | grep -q -i "busybox"; then exit 1 fi -for bin in openssl curl docker-compose docker git awk sha1sum; do +for bin in openssl curl docker git awk sha1sum; do if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi done +echo "checking docker compose version..."; +if docker --help | grep compose +then + echo '' +elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 +then + >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" + >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + >&2 echo + >&2 echo + >&2 echo -e "\e[33mContinuing...\e[0m" + sleep 3 + +else + >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" + exit 1 +fi + if [ -f mailcow.conf ]; then read -r -p "A config file exists and will be overwritten, are you sure you want to continue? [y/N] " response case $response in @@ -144,7 +163,7 @@ DBROOT=$(LC_ALL=C &2 echo -e "\e[31mCannot find ${bin} in local PATH, exiting...\e[0m" exit 1 fi done + + echo "checking docker compose version..."; + if docker --help | grep compose + then + echo '' + elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 + then + >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" + >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + >&2 echo + >&2 echo + >&2 echo -e "\e[33mContinuing...\e[0m" + sleep 3 + + else + >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" + exit 1 + fi + if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then >&2 echo -e "\e[31mBusyBox grep detected on local system, please install GNU grep\e[0m" exit 1 @@ -111,7 +131,7 @@ function preflight_remote_checks() { exit 1 fi - for bin in rsync docker-compose docker; do + for bin in rsync docker; do if ! ssh -o StrictHostKeyChecking=no \ -i "${REMOTE_SSH_KEY}" \ ${REMOTE_SSH_HOST} \ @@ -122,6 +142,32 @@ function preflight_remote_checks() { fi done + echo "checking docker compose version on remote..."; + if ssh -q -o StrictHostKeyChecking=no \ + -i "${REMOTE_SSH_KEY}" \ + ${REMOTE_SSH_HOST} \ + -p ${REMOTE_SSH_PORT} \ + -t docker --help | grep compose + then + COMPOSE_COMMAND="docker compose" + elif ssh -q -o StrictHostKeyChecking=no \ + -i "${REMOTE_SSH_KEY}" \ + ${REMOTE_SSH_HOST} \ + -p ${REMOTE_SSH_PORT} \ + 'docker-compose version --short' | grep -m1 "^1" > /dev/null 2>&1 + then + >&2 echo -e "\e[31mWARN: The remote is using Docker-Compose v1!\e[0m" + >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2 on remote.\e[0m" + >&2 echo + >&2 echo + >&2 echo -e "\e[33mContinuing...\e[0m" + sleep 3 + COMPOSE_COMMAND="docker-compose" + else + >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on the Remote Machine! Please install Docker-Compose v2 on that and re-run the script.\e[0m" + exit 1 + fi } preflight_local_checks @@ -252,16 +298,18 @@ if ! ssh -o StrictHostKeyChecking=no \ fi echo "OK" -echo -e "\033[1mPulling images on remote...\033[0m" -if ! ssh -o StrictHostKeyChecking=no \ - -i "${REMOTE_SSH_KEY}" \ - ${REMOTE_SSH_HOST} \ - -p ${REMOTE_SSH_PORT} \ - docker-compose -f "${SCRIPT_DIR}/../docker-compose.yml" pull --no-parallel 2>&1 ; then - >&2 echo -e "\e[31m[ERR]\e[0m - Could not pull images on remote" -fi + echo -e "\e[33mPulling images on remote...\e[0m" + echo -e "\e[33mProcess is NOT stuck! Please wait...\e[0m" -echo -e "\033[1mForcing garbage cleanup on remote...\033[0m" + if ! ssh -o StrictHostKeyChecking=no \ + -i "${REMOTE_SSH_KEY}" \ + ${REMOTE_SSH_HOST} \ + -p ${REMOTE_SSH_PORT} \ + $COMPOSE_COMMAND -f "${SCRIPT_DIR}/../docker-compose.yml" pull --no-parallel --quiet 2>&1 ; then + >&2 echo -e "\e[31m[ERR]\e[0m - Could not pull images on remote" + fi + +echo -e "\033[1mExecuting update script and forcing garbage cleanup on remote...\033[0m" if ! ssh -o StrictHostKeyChecking=no \ -i "${REMOTE_SSH_KEY}" \ ${REMOTE_SSH_HOST} \ diff --git a/helper-scripts/backup_and_restore.sh b/helper-scripts/backup_and_restore.sh index 9f7533ca..6d573513 100755 --- a/helper-scripts/backup_and_restore.sh +++ b/helper-scripts/backup_and_restore.sh @@ -76,6 +76,31 @@ else CMPS_PRJ=$(echo ${COMPOSE_PROJECT_NAME} | tr -cd "[0-9A-Za-z-_]") fi +echo "checking docker compose version..."; +if docker --help | grep compose +then + COMPOSE_COMMAND="docker compose" +elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 +then + >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" + >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + >&2 echo + >&2 echo + >&2 echo -e "\e[33mContinuing...\e[0m" + sleep 3 + COMPOSE_COMMAND="docker-compose" +else + >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" + exit 1 +fi + +if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then + >&2 echo -e "\e[31mBusyBox grep detected on local system, please install GNU grep\e[0m" + exit 1 +fi + + function backup() { DATE=$(date +"%Y-%m-%d-%H-%M-%S") mkdir -p "${BACKUP_LOCATION}/mailcow-${DATE}" @@ -226,7 +251,7 @@ function restore() { continue else echo "Stopping mailcow..." - docker-compose -f ${COMPOSE_FILE} --env-file ${ENV_FILE} down + ${COMPOSE_COMMAND} -f ${COMPOSE_FILE} --env-file ${ENV_FILE} down fi #docker stop $(docker ps -qf name=mysql-mailcow) if [[ -d "${RESTORE_LOCATION}/mysql" ]]; then @@ -264,7 +289,7 @@ function restore() { sed -i --follow-symlinks "/DBROOT/c\DBROOT=${DBROOT}" ${SCRIPT_DIR}/../mailcow.conf source ${SCRIPT_DIR}/../mailcow.conf echo "Starting mailcow..." - docker-compose -f ${COMPOSE_FILE} --env-file ${ENV_FILE} up -d + ${COMPOSE_COMMAND} -f ${COMPOSE_FILE} --env-file ${ENV_FILE} up -d #docker start $(docker ps -aqf name=mysql-mailcow) fi ;; diff --git a/update.sh b/update.sh index 1c564c8e..1680da50 100755 --- a/update.sh +++ b/update.sh @@ -40,10 +40,31 @@ PATH=$PATH:/opt/bin umask 0022 -for bin in curl docker-compose docker git awk sha1sum; do +for bin in curl docker git awk sha1sum; do if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi done + +echo "checking docker compose version..."; +if docker --help | grep compose +then + COMPOSE_COMMAND="docker compose" + +elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 +then + >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" + >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + >&2 echo + >&2 echo + >&2 echo -e "\e[33mContinuing...\e[0m" + sleep 3 + COMPOSE_COMMAND="docker-compose" + +else + >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" + exit 1 +fi export LC_ALL=C DATE=$(date +%Y-%m-%d_%H_%M_%S) BRANCH=$(cd ${SCRIPT_DIR}; git rev-parse --abbrev-ref HEAD) @@ -235,9 +256,6 @@ while (($#)); do echo -e "\e[32mRunning in forced mode...\e[0m" FORCE=y ;; - --no-update-compose) - NO_UPDATE_COMPOSE=y - ;; --skip-ping-check) SKIP_PING_CHECK=y ;; @@ -247,7 +265,6 @@ while (($#)); do -c|--check - Check for updates and exit (exit codes => 0: update available, 3: no updates) --ours - Use merge strategy option "ours" to solve conflicts in favor of non-mailcow code (local changes over remote changes), not recommended! --gc - Run garbage collector to delete old image tags - --no-update-compose - Do not update docker-compose --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). @@ -264,7 +281,7 @@ source mailcow.conf DOTS=${MAILCOW_HOSTNAME//[^.]}; if [ ${#DOTS} -lt 2 ]; then echo "MAILCOW_HOSTNAME (${MAILCOW_HOSTNAME}) is not a FQDN!" - echo "Please change it to a FQDN and run docker-compose down followed by docker-compose up -d" + echo "Please change it to a FQDN and run ${COMPOSE_COMMAND} down followed by ${COMPOSE_COMMAND} up -d" exit 1 fi @@ -578,13 +595,13 @@ if [ ! $FORCE ]; then fi echo -e "\e[32mValidating docker-compose stack configuration...\e[0m" -if ! docker-compose config -q; then +if ! ${COMPOSE_COMMAND} config -q; then echo -e "\e[31m\nOh no, something went wrong. Please check the error message above.\e[0m" exit 1 fi echo -e "\e[32mChecking for conflicting bridges...\e[0m" -MAILCOW_BRIDGE=$(docker-compose config | grep -i com.docker.network.bridge.name | cut -d':' -f2) +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) @@ -604,8 +621,8 @@ prefetch_images echo -e "\e[32mStopping mailcow...\e[0m" sleep 2 -MAILCOW_CONTAINERS=($(docker-compose ps -q)) -docker-compose down +MAILCOW_CONTAINERS=($(${COMPOSE_COMMAND} ps -q)) +${COMPOSE_COMMAND} down echo -e "\e[32mChecking for remaining containers...\e[0m" sleep 2 for container in "${MAILCOW_CONTAINERS[@]}"; do @@ -642,51 +659,16 @@ elif [[ ${MERGE_RETURN} == 1 ]]; then elif [[ ${MERGE_RETURN} != 0 ]]; then echo -e "\e[31m\nOh no, something went wrong. Please check the error message above.\e[0m" echo - echo "Run docker-compose up -d to restart your stack without updates or try again after fixing the mentioned errors." + echo "Run ${COMPOSE_COMMAND} up -d to restart your stack without updates or try again after fixing the mentioned errors." exit 1 fi -if [[ ${NO_UPDATE_COMPOSE} == "y" ]]; then - echo -e "\e[33mNot fetching latest docker-compose, please check for updates manually!\e[0m" -elif [[ -e /etc/alpine-release ]]; then - echo -e "\e[33mNot fetching latest docker-compose, because you are using Alpine Linux without glibc support. Please update docker-compose via apk!\e[0m" -else - echo -e "\e[32mFetching new docker-compose version...\e[0m" - echo -e "\e[32mTrying to determine GLIBC version...\e[0m" - if ldd --version > /dev/null; then - GLIBC_V=$(ldd --version | grep -E '(GLIBC|GNU libc)' | rev | cut -d ' ' -f1 | rev | cut -d '.' -f2) - if [ ! -z "${GLIBC_V}" ] && [ ${GLIBC_V} -gt 27 ]; then - DC_DL_SUFFIX= - else - DC_DL_SUFFIX=legacy - fi - else - DC_DL_SUFFIX=legacy - fi - sleep 1 - if [[ ! -z $(which pip) && $(pip list --local 2>&1 | grep -v DEPRECATION | grep -c docker-compose) == 1 ]]; then - true - #prevent breaking a working docker-compose installed with pip - elif [[ $(curl -sL -w "%{http_code}" https://www.servercow.de/docker-compose/latest.php?vers=${DC_DL_SUFFIX} -o /dev/null) == "200" ]]; then - LATEST_COMPOSE=$(curl -#L https://www.servercow.de/docker-compose/latest.php) - COMPOSE_VERSION=$(docker-compose version --short) - if [[ "$LATEST_COMPOSE" != "$COMPOSE_VERSION" ]]; then - COMPOSE_PATH=$(which docker-compose) - if [[ -w ${COMPOSE_PATH} ]]; then - curl -#L https://github.com/docker/compose/releases/download/${LATEST_COMPOSE}/docker-compose-$(uname -s)-$(uname -m) > $COMPOSE_PATH - chmod +x $COMPOSE_PATH - else - echo -e "\e[33mWARNING: $COMPOSE_PATH is not writable, but new version $LATEST_COMPOSE is available (installed: $COMPOSE_VERSION)\e[0m" - fi - fi - else - echo -e "\e[33mCannot determine latest docker-compose version, skipping...\e[0m" - fi -fi +echo -e "\e[33mNot fetching latest docker-compose, please check for updates manually!\e[0m" +sleep 3 echo -e "\e[32mFetching new images, if any...\e[0m" sleep 2 -docker-compose pull +${COMPOSE_COMMAND} pull # Fix missing SSL, does not overwrite existing files [[ ! -d data/assets/ssl ]] && mkdir -p data/assets/ssl @@ -707,9 +689,6 @@ fi # Checking for old project name bug sed -i --follow-symlinks 's#COMPOSEPROJECT_NAME#COMPOSE_PROJECT_NAME#g' mailcow.conf -# Checking old, wrong bindings -sed -i --follow-symlinks 's/HTTP_BIND=0.0.0.0/HTTP_BIND=/g' mailcow.conf -sed -i --follow-symlinks 's/HTTPS_BIND=0.0.0.0/HTTPS_BIND=/g' mailcow.conf # Fix Rspamd maps if [ -f data/conf/rspamd/custom/global_from_blacklist.map ]; then @@ -744,11 +723,11 @@ else fi if [[ ${SKIP_START} == "y" ]]; then - echo -e "\e[33mNot starting mailcow, please run \"docker-compose up -d --remove-orphans\" to start mailcow.\e[0m" + echo -e "\e[33mNot starting mailcow, please run \"${COMPOSE_COMMAND} up -d --remove-orphans\" to start mailcow.\e[0m" else echo -e "\e[32mStarting mailcow...\e[0m" sleep 2 - docker-compose up -d --remove-orphans + ${COMPOSE_COMMAND} up -d --remove-orphans fi echo -e "\e[32mCollecting garbage...\e[0m" @@ -763,4 +742,4 @@ fi #echo #git reflog --color=always | grep "Before update on " #echo -#echo "Use \"git reset --hard hash-on-the-left\" and run docker-compose up -d afterwards." +#echo "Use \"git reset --hard hash-on-the-left\" and run ${COMPOSE_COMMAND} up -d afterwards." From 7bcc8bd3a2b3cfba0c9e5c85018120030bf847bc Mon Sep 17 00:00:00 2001 From: Niklas Meyer Date: Tue, 7 Jun 2022 10:34:59 +0200 Subject: [PATCH 26/52] [Compose] Removed volume Bind from rspamd-vol --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 77b9c3cf..f87c0933 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -95,7 +95,7 @@ services: - ./data/conf/rspamd/lua/:/etc/rspamd/lua/:ro,Z - ./data/conf/rspamd/rspamd.conf.local:/etc/rspamd/rspamd.conf.local:Z - ./data/conf/rspamd/rspamd.conf.override:/etc/rspamd/rspamd.conf.override:Z - - rspamd-vol-1:/var/lib/rspamd:z + - rspamd-vol-1:/var/lib/rspamd restart: always hostname: rspamd dns: From 08d0f9448e481a2f72e5b5d397b483c1ab67233c Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Tue, 7 Jun 2022 13:59:59 +0200 Subject: [PATCH 27/52] [Compose] move then in if statement --- generate_config.sh | 27 +++++++------- helper-scripts/_cold-standby.sh | 53 +++++++++++++--------------- helper-scripts/backup_and_restore.sh | 28 +++++++-------- update.sh | 30 +++++++--------- 4 files changed, 62 insertions(+), 76 deletions(-) diff --git a/generate_config.sh b/generate_config.sh index 45cfaf56..66c9203a 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -30,22 +30,19 @@ for bin in openssl curl docker git awk sha1sum; do done echo "checking docker compose version..."; -if docker --help | grep compose -then - echo '' -elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 -then - >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" - >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" - >&2 echo - >&2 echo - >&2 echo -e "\e[33mContinuing...\e[0m" - sleep 3 - +if docker --help | grep compose then + echo '' +elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 then + >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" + >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + >&2 echo + >&2 echo + >&2 echo -e "\e[33mContinuing...\e[0m" + sleep 3 else - >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" - exit 1 + >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" + exit 1 fi if [ -f mailcow.conf ]; then diff --git a/helper-scripts/_cold-standby.sh b/helper-scripts/_cold-standby.sh index 0ebb7e1f..2ec857ac 100755 --- a/helper-scripts/_cold-standby.sh +++ b/helper-scripts/_cold-standby.sh @@ -86,22 +86,19 @@ function preflight_local_checks() { echo "checking docker compose version..."; - if docker --help | grep compose - then + if docker --help | grep compose then echo '' - elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 - then - >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" - >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" - >&2 echo - >&2 echo - >&2 echo -e "\e[33mContinuing...\e[0m" - sleep 3 - + elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 then + >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" + >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + >&2 echo + >&2 echo + >&2 echo -e "\e[33mContinuing...\e[0m" + sleep 3 else - >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" - exit 1 + >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" + exit 1 fi if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then @@ -147,26 +144,24 @@ function preflight_remote_checks() { -i "${REMOTE_SSH_KEY}" \ ${REMOTE_SSH_HOST} \ -p ${REMOTE_SSH_PORT} \ - -t docker --help | grep compose - then - COMPOSE_COMMAND="docker compose" + -t docker --help | grep compose then + COMPOSE_COMMAND="docker compose" elif ssh -q -o StrictHostKeyChecking=no \ -i "${REMOTE_SSH_KEY}" \ ${REMOTE_SSH_HOST} \ -p ${REMOTE_SSH_PORT} \ - 'docker-compose version --short' | grep -m1 "^1" > /dev/null 2>&1 - then - >&2 echo -e "\e[31mWARN: The remote is using Docker-Compose v1!\e[0m" - >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2 on remote.\e[0m" - >&2 echo - >&2 echo - >&2 echo -e "\e[33mContinuing...\e[0m" - sleep 3 - COMPOSE_COMMAND="docker-compose" + 'docker-compose version --short' | grep -m1 "^1" > /dev/null 2>&1 then + >&2 echo -e "\e[31mWARN: The remote is using Docker-Compose v1!\e[0m" + >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2 on remote.\e[0m" + >&2 echo + >&2 echo + >&2 echo -e "\e[33mContinuing...\e[0m" + sleep 3 + COMPOSE_COMMAND="docker-compose" else - >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on the Remote Machine! Please install Docker-Compose v2 on that and re-run the script.\e[0m" - exit 1 + >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on the Remote Machine! Please install Docker-Compose v2 on that and re-run the script.\e[0m" + exit 1 fi } diff --git a/helper-scripts/backup_and_restore.sh b/helper-scripts/backup_and_restore.sh index 6d573513..f0cd5c18 100755 --- a/helper-scripts/backup_and_restore.sh +++ b/helper-scripts/backup_and_restore.sh @@ -77,22 +77,20 @@ else fi echo "checking docker compose version..."; -if docker --help | grep compose -then - COMPOSE_COMMAND="docker compose" -elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 -then - >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" - >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" - >&2 echo - >&2 echo - >&2 echo -e "\e[33mContinuing...\e[0m" - sleep 3 - COMPOSE_COMMAND="docker-compose" +if docker --help | grep compose then + COMPOSE_COMMAND="docker compose" +elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 then + >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" + >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + >&2 echo + >&2 echo + >&2 echo -e "\e[33mContinuing...\e[0m" + sleep 3 + COMPOSE_COMMAND="docker-compose" else - >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" - exit 1 + >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" + exit 1 fi if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then diff --git a/update.sh b/update.sh index 1680da50..d7c65b77 100755 --- a/update.sh +++ b/update.sh @@ -46,24 +46,20 @@ done echo "checking docker compose version..."; -if docker --help | grep compose -then - COMPOSE_COMMAND="docker compose" - -elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 -then - >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" - >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" - >&2 echo - >&2 echo - >&2 echo -e "\e[33mContinuing...\e[0m" - sleep 3 - COMPOSE_COMMAND="docker-compose" - +if docker --help | grep compose then + COMPOSE_COMMAND="docker compose" +elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 then + >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" + >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + >&2 echo + >&2 echo + >&2 echo -e "\e[33mContinuing...\e[0m" + sleep 3 + COMPOSE_COMMAND="docker-compose" else - >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" - exit 1 + >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" + exit 1 fi export LC_ALL=C DATE=$(date +%Y-%m-%d_%H_%M_%S) From 958112af6b96f0f794a986eac91c4038c0d378a1 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Tue, 7 Jun 2022 14:07:35 +0200 Subject: [PATCH 28/52] [Compose] Remove >&2 in if block --- generate_config.sh | 18 ++++++------- helper-scripts/_cold-standby.sh | 38 ++++++++++++++-------------- helper-scripts/backup_and_restore.sh | 18 ++++++------- update.sh | 18 ++++++------- 4 files changed, 46 insertions(+), 46 deletions(-) diff --git a/generate_config.sh b/generate_config.sh index 66c9203a..0b01b803 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -30,18 +30,18 @@ for bin in openssl curl docker git awk sha1sum; do done echo "checking docker compose version..."; -if docker --help | grep compose then +if docker --help | grep compose; then echo '' -elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 then - >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" - >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" - >&2 echo - >&2 echo - >&2 echo -e "\e[33mContinuing...\e[0m" +elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then + echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" + echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + echo + echo + echo -e "\e[33mContinuing...\e[0m" sleep 3 else - >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" + echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" exit 1 fi diff --git a/helper-scripts/_cold-standby.sh b/helper-scripts/_cold-standby.sh index 2ec857ac..a1e2f165 100755 --- a/helper-scripts/_cold-standby.sh +++ b/helper-scripts/_cold-standby.sh @@ -86,23 +86,23 @@ function preflight_local_checks() { echo "checking docker compose version..."; - if docker --help | grep compose then + if docker --help | grep compose; then echo '' - elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 then - >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" - >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" - >&2 echo - >&2 echo - >&2 echo -e "\e[33mContinuing...\e[0m" + elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then + echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" + echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + echo + echo + echo -e "\e[33mContinuing...\e[0m" sleep 3 else - >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" + echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" exit 1 fi if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then - >&2 echo -e "\e[31mBusyBox grep detected on local system, please install GNU grep\e[0m" + echo -e "\e[31mBusyBox grep detected on local system, please install GNU grep\e[0m" exit 1 fi } @@ -144,23 +144,23 @@ function preflight_remote_checks() { -i "${REMOTE_SSH_KEY}" \ ${REMOTE_SSH_HOST} \ -p ${REMOTE_SSH_PORT} \ - -t docker --help | grep compose then + -t docker --help | grep compose; then COMPOSE_COMMAND="docker compose" elif ssh -q -o StrictHostKeyChecking=no \ -i "${REMOTE_SSH_KEY}" \ ${REMOTE_SSH_HOST} \ -p ${REMOTE_SSH_PORT} \ - 'docker-compose version --short' | grep -m1 "^1" > /dev/null 2>&1 then - >&2 echo -e "\e[31mWARN: The remote is using Docker-Compose v1!\e[0m" - >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2 on remote.\e[0m" - >&2 echo - >&2 echo - >&2 echo -e "\e[33mContinuing...\e[0m" + 'docker-compose version --short' | grep -m1 "^1" > /dev/null 2>&1; then + echo -e "\e[31mWARN: The remote is using Docker-Compose v1!\e[0m" + echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2 on remote.\e[0m" + echo + echo + echo -e "\e[33mContinuing...\e[0m" sleep 3 COMPOSE_COMMAND="docker-compose" else - >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on the Remote Machine! Please install Docker-Compose v2 on that and re-run the script.\e[0m" + echo -e "\e[31mCannot find Docker-Compose v1 or v2 on the Remote Machine! Please install Docker-Compose v2 on that and re-run the script.\e[0m" exit 1 fi } diff --git a/helper-scripts/backup_and_restore.sh b/helper-scripts/backup_and_restore.sh index f0cd5c18..dd0c2212 100755 --- a/helper-scripts/backup_and_restore.sh +++ b/helper-scripts/backup_and_restore.sh @@ -77,19 +77,19 @@ else fi echo "checking docker compose version..."; -if docker --help | grep compose then +if docker --help | grep compose; then COMPOSE_COMMAND="docker compose" -elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 then - >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" - >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" - >&2 echo - >&2 echo - >&2 echo -e "\e[33mContinuing...\e[0m" +elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then + echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" + echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + echo + echo + echo -e "\e[33mContinuing...\e[0m" sleep 3 COMPOSE_COMMAND="docker-compose" else - >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" + echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" exit 1 fi diff --git a/update.sh b/update.sh index d7c65b77..f23999ae 100755 --- a/update.sh +++ b/update.sh @@ -46,19 +46,19 @@ done echo "checking docker compose version..."; -if docker --help | grep compose then +if docker --help | grep compose; then COMPOSE_COMMAND="docker compose" -elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1 then - >&2 echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" - >&2 echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - >&2 echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" - >&2 echo - >&2 echo - >&2 echo -e "\e[33mContinuing...\e[0m" +elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then + echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" + echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + echo + echo + echo -e "\e[33mContinuing...\e[0m" sleep 3 COMPOSE_COMMAND="docker-compose" else - >&2 echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" + echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" exit 1 fi export LC_ALL=C From 74baf20feb0bf993afd400828ff85d5c0947331f Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Tue, 7 Jun 2022 14:45:19 +0200 Subject: [PATCH 29/52] Optimized if-else arguments and outputs --- generate_config.sh | 10 +++++----- helper-scripts/_cold-standby.sh | 21 +++++++++++---------- helper-scripts/backup_and_restore.sh | 9 +++++---- update.sh | 11 ++++++----- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/generate_config.sh b/generate_config.sh index 0b01b803..601d8ca2 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -30,12 +30,12 @@ for bin in openssl curl docker git awk sha1sum; do done echo "checking docker compose version..."; -if docker --help | grep compose; then - echo '' +if docker compose >/dev/null 2>&1; then + echo -e "\e[32mFound Compose v2!\e[0m" elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then - echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" - echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" + echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + echo -e "\e[33mPlease consider a upgrade to Docker-Compose v2.\e[0m" echo echo echo -e "\e[33mContinuing...\e[0m" diff --git a/helper-scripts/_cold-standby.sh b/helper-scripts/_cold-standby.sh index a1e2f165..ca205605 100755 --- a/helper-scripts/_cold-standby.sh +++ b/helper-scripts/_cold-standby.sh @@ -86,12 +86,12 @@ function preflight_local_checks() { echo "checking docker compose version..."; - if docker --help | grep compose; then - echo '' + if docker compose >/dev/null 2>&1; then + echo -e "\e[32mFound Compose v2 on local machine!\e[0m" elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then - echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" - echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" + echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + echo -e "\e[33mPlease consider a upgrade to Docker-Compose v2.\e[0m" echo echo echo -e "\e[33mContinuing...\e[0m" @@ -144,16 +144,17 @@ function preflight_remote_checks() { -i "${REMOTE_SSH_KEY}" \ ${REMOTE_SSH_HOST} \ -p ${REMOTE_SSH_PORT} \ - -t docker --help | grep compose; then + -t 'docker compose' >/dev/null 2>&1; then + echo -e "\e[32mFound Compose v2 on remote!\e[0m" COMPOSE_COMMAND="docker compose" elif ssh -q -o StrictHostKeyChecking=no \ -i "${REMOTE_SSH_KEY}" \ ${REMOTE_SSH_HOST} \ -p ${REMOTE_SSH_PORT} \ - 'docker-compose version --short' | grep -m1 "^1" > /dev/null 2>&1; then - echo -e "\e[31mWARN: The remote is using Docker-Compose v1!\e[0m" - echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2 on remote.\e[0m" + -t 'docker-compose version --short' | grep -m1 "^1" > /dev/null 2>&1; then + echo -e "\e[33mWARN: The remote is using Docker-Compose v1!\e[0m" + echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + echo -e "\e[33mPlease consider a upgrade to Docker-Compose v2 on remote.\e[0m" echo echo echo -e "\e[33mContinuing...\e[0m" diff --git a/helper-scripts/backup_and_restore.sh b/helper-scripts/backup_and_restore.sh index dd0c2212..b89c19d4 100755 --- a/helper-scripts/backup_and_restore.sh +++ b/helper-scripts/backup_and_restore.sh @@ -77,12 +77,13 @@ else fi echo "checking docker compose version..."; -if docker --help | grep compose; then +if docker compose >/dev/null 2>&1; then + echo -e "\e[32mFound Compose v2!\e[0m" COMPOSE_COMMAND="docker compose" elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then - echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" - echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" + echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + echo -e "\e[33mPlease consider a upgrade to Docker-Compose v2.\e[0m" echo echo echo -e "\e[33mContinuing...\e[0m" diff --git a/update.sh b/update.sh index f23999ae..6d01edba 100755 --- a/update.sh +++ b/update.sh @@ -46,12 +46,13 @@ done echo "checking docker compose version..."; -if docker --help | grep compose; then +if docker compose >/dev/null 2>&1; then + echo -e "\e[32mFound Compose v2!\e[0m" COMPOSE_COMMAND="docker compose" elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then - echo -e "\e[31mWARN: Your machine is using Docker-Compose v1!\e[0m" - echo -e "\e[31mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - echo -e "\e[31mPlease consider a upgrade to Docker-Compose v2.\e[0m" + echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" + echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" + echo -e "\e[33mPlease consider a upgrade to Docker-Compose v2.\e[0m" echo echo echo -e "\e[33mContinuing...\e[0m" @@ -738,4 +739,4 @@ fi #echo #git reflog --color=always | grep "Before update on " #echo -#echo "Use \"git reset --hard hash-on-the-left\" and run ${COMPOSE_COMMAND} up -d afterwards." +#echo "Use \"git reset --hard hash-on-the-left\" and run ${COMPOSE_COMMAND} up -d afterwards." \ No newline at end of file From fd853cfc6fef17657432c562611aa1c6fdb3265a Mon Sep 17 00:00:00 2001 From: Niklas Meyer <62480600+DerLinkman@users.noreply.github.com> Date: Tue, 7 Jun 2022 17:50:42 +0200 Subject: [PATCH 30/52] [Compose] Rollback watchdog to 1.96 Due to https://github.com/nagios-plugins/nagios-plugins/pull/649 which cause the Certificate Check to fail. --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index f87c0933..e3b08637 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -447,7 +447,7 @@ services: - /lib/modules:/lib/modules:ro watchdog-mailcow: - image: mailcow/watchdog:1.97 + image: mailcow/watchdog:1.96 dns: - ${IPV4_NETWORK:-172.22.1}.254 tmpfs: From 141b397c82b717236bdb3a76ec7684442bf694e7 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Tue, 7 Jun 2022 18:34:41 +0200 Subject: [PATCH 31/52] Fix Docker Compose recognition for docker-compose syntax --- generate_config.sh | 3 +++ helper-scripts/_cold-standby.sh | 3 +++ helper-scripts/backup_and_restore.sh | 3 +++ update.sh | 3 +++ 4 files changed, 12 insertions(+) diff --git a/generate_config.sh b/generate_config.sh index 601d8ca2..35601098 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -32,6 +32,9 @@ done echo "checking docker compose version..."; if docker compose >/dev/null 2>&1; then echo -e "\e[32mFound Compose v2!\e[0m" +elif docker-compose version --short | grep -m1 "^2" > /dev/null 2>&1; then + echo -e "\e[32mFound Compose v2!\e[0m" + COMPOSE_COMMAND="docker compose" elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" diff --git a/helper-scripts/_cold-standby.sh b/helper-scripts/_cold-standby.sh index ca205605..534add48 100755 --- a/helper-scripts/_cold-standby.sh +++ b/helper-scripts/_cold-standby.sh @@ -88,6 +88,9 @@ function preflight_local_checks() { echo "checking docker compose version..."; if docker compose >/dev/null 2>&1; then echo -e "\e[32mFound Compose v2 on local machine!\e[0m" + elif docker-compose version --short | grep -m1 "^2" > /dev/null 2>&1; then + echo -e "\e[32mFound Compose v2!\e[0m" + COMPOSE_COMMAND="docker compose" elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" diff --git a/helper-scripts/backup_and_restore.sh b/helper-scripts/backup_and_restore.sh index b89c19d4..15407aae 100755 --- a/helper-scripts/backup_and_restore.sh +++ b/helper-scripts/backup_and_restore.sh @@ -80,6 +80,9 @@ echo "checking docker compose version..."; if docker compose >/dev/null 2>&1; then echo -e "\e[32mFound Compose v2!\e[0m" COMPOSE_COMMAND="docker compose" +elif docker-compose version --short | grep -m1 "^2" > /dev/null 2>&1; then + echo -e "\e[32mFound Compose v2!\e[0m" + COMPOSE_COMMAND="docker compose" elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" diff --git a/update.sh b/update.sh index 6d01edba..16e6f9a9 100755 --- a/update.sh +++ b/update.sh @@ -49,6 +49,9 @@ echo "checking docker compose version..."; if docker compose >/dev/null 2>&1; then echo -e "\e[32mFound Compose v2!\e[0m" COMPOSE_COMMAND="docker compose" +elif docker-compose version --short | grep -m1 "^2" > /dev/null 2>&1; then + echo -e "\e[32mFound Compose v2!\e[0m" + COMPOSE_COMMAND="docker compose" elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" From 5d14baa43a433638dc9500866039eea1546ed926 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Tue, 7 Jun 2022 18:38:43 +0200 Subject: [PATCH 32/52] Fixed typo for previous commit --- generate_config.sh | 2 +- helper-scripts/_cold-standby.sh | 9 ++++++++- helper-scripts/backup_and_restore.sh | 2 +- update.sh | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/generate_config.sh b/generate_config.sh index 35601098..800f0b53 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -34,7 +34,7 @@ if docker compose >/dev/null 2>&1; then echo -e "\e[32mFound Compose v2!\e[0m" elif docker-compose version --short | grep -m1 "^2" > /dev/null 2>&1; then echo -e "\e[32mFound Compose v2!\e[0m" - COMPOSE_COMMAND="docker compose" + COMPOSE_COMMAND="docker-compose" elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" diff --git a/helper-scripts/_cold-standby.sh b/helper-scripts/_cold-standby.sh index 534add48..14200954 100755 --- a/helper-scripts/_cold-standby.sh +++ b/helper-scripts/_cold-standby.sh @@ -90,7 +90,7 @@ function preflight_local_checks() { echo -e "\e[32mFound Compose v2 on local machine!\e[0m" elif docker-compose version --short | grep -m1 "^2" > /dev/null 2>&1; then echo -e "\e[32mFound Compose v2!\e[0m" - COMPOSE_COMMAND="docker compose" + COMPOSE_COMMAND="docker-compose" elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" @@ -150,6 +150,13 @@ function preflight_remote_checks() { -t 'docker compose' >/dev/null 2>&1; then echo -e "\e[32mFound Compose v2 on remote!\e[0m" COMPOSE_COMMAND="docker compose" + elif ssh -q -o StrictHostKeyChecking=no \ + -i "${REMOTE_SSH_KEY}" \ + ${REMOTE_SSH_HOST} \ + -p ${REMOTE_SSH_PORT} \ + -t 'docker-compose version --short' | grep -m1 "^2" > /dev/null 2>&1; then + echo -e "\e[32mFound Compose v2!\e[0m" + COMPOSE_COMMAND="docker-compose" elif ssh -q -o StrictHostKeyChecking=no \ -i "${REMOTE_SSH_KEY}" \ ${REMOTE_SSH_HOST} \ diff --git a/helper-scripts/backup_and_restore.sh b/helper-scripts/backup_and_restore.sh index 15407aae..8136def3 100755 --- a/helper-scripts/backup_and_restore.sh +++ b/helper-scripts/backup_and_restore.sh @@ -82,7 +82,7 @@ if docker compose >/dev/null 2>&1; then COMPOSE_COMMAND="docker compose" elif docker-compose version --short | grep -m1 "^2" > /dev/null 2>&1; then echo -e "\e[32mFound Compose v2!\e[0m" - COMPOSE_COMMAND="docker compose" + COMPOSE_COMMAND="docker-compose" elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" diff --git a/update.sh b/update.sh index 16e6f9a9..0b9e12d2 100755 --- a/update.sh +++ b/update.sh @@ -51,7 +51,7 @@ if docker compose >/dev/null 2>&1; then COMPOSE_COMMAND="docker compose" elif docker-compose version --short | grep -m1 "^2" > /dev/null 2>&1; then echo -e "\e[32mFound Compose v2!\e[0m" - COMPOSE_COMMAND="docker compose" + COMPOSE_COMMAND="docker-compose" elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" From 7ae7f25580dbab0e49ff0d208ba876be1485d468 Mon Sep 17 00:00:00 2001 From: andryyy Date: Sat, 11 Jun 2022 11:42:11 +0200 Subject: [PATCH 33/52] [Web] Re-use DKIM key if available --- data/web/inc/functions.dkim.inc.php | 2 +- data/web/inc/functions.mailbox.inc.php | 22 ++++++++++++++++++++-- data/web/lang/lang.de.json | 1 + data/web/lang/lang.en.json | 1 + 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/data/web/inc/functions.dkim.inc.php b/data/web/inc/functions.dkim.inc.php index 85d3c6c1..29b32d5d 100644 --- a/data/web/inc/functions.dkim.inc.php +++ b/data/web/inc/functions.dkim.inc.php @@ -197,7 +197,7 @@ function dkim($_action, $_data = null, $privkey = false) { return false; } try { - dkim('delete', (array)$domain); + dkim('delete', array('domains' => $domain)); $redis->hSet('DKIM_PUB_KEYS', $domain, $pem_public_key); $redis->hSet('DKIM_SELECTORS', $domain, $dkim_selector); $redis->hSet('DKIM_PRIV_KEYS', $dkim_selector . '.' . $domain, $private_key_normalized); diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 623f6c38..7f8ff3ac 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -599,7 +599,16 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ratelimit('edit', 'domain', array('rl_value' => $_data['rl_value'], 'rl_frame' => $_data['rl_frame'], 'object' => $domain)); } if (!empty($_data['key_size']) && !empty($_data['dkim_selector'])) { - dkim('add', array('key_size' => $_data['key_size'], 'dkim_selector' => $_data['dkim_selector'], 'domains' => $domain)); + if (!empty($redis->hGet('DKIM_SELECTORS', $domain))) { + $_SESSION['return'][] = array( + 'type' => 'success', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'domain_add_dkim_available' + ); + } + else { + dkim('add', array('key_size' => $_data['key_size'], 'dkim_selector' => $_data['dkim_selector'], 'domains' => $domain)); + } } if (!empty($restart_sogo)) { $restart_response = json_decode(docker('post', 'sogo-mailcow', 'restart'), true); @@ -929,7 +938,16 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ratelimit('edit', 'domain', array('rl_value' => $_data['rl_value'], 'rl_frame' => $_data['rl_frame'], 'object' => $alias_domain)); } if (!empty($_data['key_size']) && !empty($_data['dkim_selector'])) { - dkim('add', array('key_size' => $_data['key_size'], 'dkim_selector' => $_data['dkim_selector'], 'domains' => $alias_domain)); + if (!empty($redis->hGet('DKIM_SELECTORS', $alias_domain))) { + $_SESSION['return'][] = array( + 'type' => 'success', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'domain_add_dkim_available' + ); + } + else { + dkim('add', array('key_size' => $_data['key_size'], 'dkim_selector' => $_data['dkim_selector'], 'domains' => $alias_domain)); + } } $_SESSION['return'][] = array( 'type' => 'success', diff --git a/data/web/lang/lang.de.json b/data/web/lang/lang.de.json index 44dc8285..7167290f 100644 --- a/data/web/lang/lang.de.json +++ b/data/web/lang/lang.de.json @@ -921,6 +921,7 @@ "deleted_syncjob": "Sync-Jobs-ID %s gelöscht", "deleted_syncjobs": "Sync-Jobs gelöscht: %s", "dkim_added": "DKIM-Key %s wurde hinzugefügt", + "domain_add_dkim_available": "Ein DKIM-Key existierte bereits", "dkim_duplicated": "DKIM-Key der Domain %s wurde auf Domain %s kopiert", "dkim_removed": "DKIM-Key %s wurde entfernt", "domain_added": "Domain %s wurde angelegt", diff --git a/data/web/lang/lang.en.json b/data/web/lang/lang.en.json index 8445641f..0a384071 100644 --- a/data/web/lang/lang.en.json +++ b/data/web/lang/lang.en.json @@ -928,6 +928,7 @@ "deleted_syncjob": "Deleted syncjob ID %s", "deleted_syncjobs": "Deleted syncjobs: %s", "dkim_added": "DKIM key %s has been saved", + "domain_add_dkim_available": "A DKIM key did already exist", "dkim_duplicated": "DKIM key for domain %s has been copied to %s", "dkim_removed": "DKIM key %s has been removed", "domain_added": "Added domain %s", From 71db83efce069c8f241bdfd4ecac56babc9b2610 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Mon, 13 Jun 2022 12:46:39 +0200 Subject: [PATCH 34/52] hotfix imapsync --- data/web/inc/functions.mailbox.inc.php | 61 +++++++++++- data/web/inc/vars.inc.php | 132 +++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 5 deletions(-) diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 7f8ff3ac..d6a07eab 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -336,9 +336,34 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $mins_interval = $_data['mins_interval']; $enc1 = $_data['enc1']; $custom_params = (empty(trim($_data['custom_params']))) ? '' : trim($_data['custom_params']); - // Workaround, fixme - if (stripos($custom_params, 'pipemess') || stripos($custom_params, 'pipemes')) { - $custom_params = ''; + + // validate custom params + foreach (explode(' -', $custom_params) as $param){ + if (str_contains($param, ' ')) { + // bad char + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'bad character SPACE' + ); + return false; + } + + // extract option + if (str_contains($param, '=')) $param = explode('=', $param)[0]; + // remove first char if first char is - + if ($param[0] == '-') $param = ltrim($param, $param[0]); + + // check if param is whitelisted + if (!in_array(strtolower($param), $GLOBALS["IMAPSYNC_OPTIONS"]["whitelist"])){ + // bad option + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'bad option '. $param + ); + return false; + } } if (empty($subfolder2)) { $subfolder2 = ""; @@ -1764,8 +1789,34 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ); continue; } - if (stripos($custom_params, 'pipemess') || stripos($custom_params, 'pipemes')) { - $custom_params = ''; + + // validate custom params + foreach (explode(' -', $custom_params) as $param){ + if (str_contains($param, ' ')) { + // bad char + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'bad character SPACE' + ); + return false; + } + + // extract option + if (str_contains($param, '=')) $param = explode('=', $param)[0]; + // remove first char if first char is - + if ($param[0] == '-') $param = ltrim($param, $param[0]); + + // check if param is whitelisted + if (!in_array(strtolower($param), $GLOBALS["IMAPSYNC_OPTIONS"]["whitelist"])){ + // bad option + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'bad option '. $param + ); + return false; + } } if (empty($subfolder2)) { $subfolder2 = ""; diff --git a/data/web/inc/vars.inc.php b/data/web/inc/vars.inc.php index c8e79bc4..6e08be13 100644 --- a/data/web/inc/vars.inc.php +++ b/data/web/inc/vars.inc.php @@ -228,3 +228,135 @@ $RSPAMD_MAPS = array( 'Monitoring Hosts' => 'monitoring_nolog.map' ) ); + + +$IMAPSYNC_OPTIONS = array( + 'whitelist' => array( + 'log', + 'showpasswords', + 'nossl1', + 'nossl2', + 'ssl2', + 'notls1', + 'notls2', + 'tls2', + 'debugssl', + 'sslargs1', + 'sslargs2', + 'authmech1', + 'authmech2', + 'authuser1', + 'authuser2', + 'proxyauth1', + 'proxyauth2', + 'authmd51', + 'authmd52', + 'domain1', + 'domain2', + 'oauthaccesstoken1', + 'oauthaccesstoken2', + 'oauthdirect1', + 'oauthdirect2', + 'folder', + 'folder', + 'folderrec', + 'folderrec', + 'folderfirst', + 'folderfirst', + 'folderlast', + 'folderlast', + 'nomixfolders', + 'skipemptyfolders', + 'include', + 'include', + 'subfolder1', + 'subscribed', + 'subscribe', + 'prefix1', + 'prefix2', + 'sep1', + 'sep2', + 'nofoldersizesatend', + 'justfoldersizes', + 'pidfile', + 'pidfilelocking', + 'nolog', + 'logfile', + 'logdir', + 'debugcrossduplicates', + 'disarmreadreceipts', + 'truncmess', + 'synclabels', + 'resynclabels', + 'resyncflags', + 'noresyncflags', + 'filterbuggyflags', + 'expunge1', + 'noexpunge1', + 'delete1emptyfolders', + 'delete2folders', + 'noexpunge2', + 'nouidexpunge2', + 'syncinternaldates', + 'idatefromheader', + 'maxsize', + 'minsize', + 'minage', + 'search', + 'search1', + 'search2', + 'noabletosearch', + 'noabletosearch1', + 'noabletosearch2', + 'maxlinelength', + 'useheader', + 'useheader', + 'syncduplicates', + 'usecache', + 'nousecache', + 'useuid', + 'syncacls', + 'nosyncacls', + 'debug', + 'debugfolders', + 'debugcontent', + 'debugflags', + 'debugimap1', + 'debugimap2', + 'debugimap', + 'debugmemory', + 'errorsmax', + 'tests', + 'testslive', + 'testslive6', + 'gmail1', + 'gmail2', + 'office1', + 'office2', + 'exchange1', + 'exchange2', + 'domino1', + 'domino2', + 'keepalive1', + 'keepalive2', + 'maxmessagespersecond', + 'maxbytesafter', + 'maxsleep', + 'abort', + 'exitwhenover', + 'noid', + 'justconnect', + 'justlogin', + 'justfolders' + ), + 'blacklist' => array( + 'skipmess', + 'delete2foldersonly', + 'delete2foldersbutnot', + 'regexflag', + 'regexmess', + 'pipemess', + 'regextrans2', + 'maxlinelengthcmd' + ) +); From 7166696aa2682617836c254e9243a3120a9243d0 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 16 Jun 2022 12:28:04 +0200 Subject: [PATCH 35/52] Readded Compose Standalone Download --- update.sh | 103 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 38 deletions(-) diff --git a/update.sh b/update.sh index 0b9e12d2..26a09785 100755 --- a/update.sh +++ b/update.sh @@ -44,27 +44,6 @@ for bin in curl docker git awk sha1sum; do if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi done - -echo "checking docker compose version..."; -if docker compose >/dev/null 2>&1; then - echo -e "\e[32mFound Compose v2!\e[0m" - COMPOSE_COMMAND="docker compose" -elif docker-compose version --short | grep -m1 "^2" > /dev/null 2>&1; then - echo -e "\e[32mFound Compose v2!\e[0m" - COMPOSE_COMMAND="docker-compose" -elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then - echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" - echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - echo -e "\e[33mPlease consider a upgrade to Docker-Compose v2.\e[0m" - echo - echo - echo -e "\e[33mContinuing...\e[0m" - sleep 3 - COMPOSE_COMMAND="docker-compose" -else - echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" - exit 1 -fi export LC_ALL=C DATE=$(date +%Y-%m-%d_%H_%M_%S) BRANCH=$(cd ${SCRIPT_DIR}; git rev-parse --abbrev-ref HEAD) @@ -218,6 +197,50 @@ migrate_docker_nat() { fi } +update_compose(){ +if [[ ${NO_UPDATE_COMPOSE} == "y" ]]; then + echo -e "\e[33mNot fetching latest docker-compose, please check for updates manually!\e[0m" + return 0 +elif [[ -e /etc/alpine-release ]]; then + echo -e "\e[33mNot fetching latest docker-compose, because you are using Alpine Linux without glibc support. Please update docker-compose via apk!\e[0m" + return 0 +else + echo -e "\e[32mFetching new docker-compose version...\e[0m" + echo -e "\e[32mTrying to determine GLIBC version...\e[0m" + if ldd --version > /dev/null; then + GLIBC_V=$(ldd --version | grep -E '(GLIBC|GNU libc)' | rev | cut -d ' ' -f1 | rev | cut -d '.' -f2) + if [ ! -z "${GLIBC_V}" ] && [ ${GLIBC_V} -gt 27 ]; then + DC_DL_SUFFIX= + else + DC_DL_SUFFIX=legacy + fi + else + DC_DL_SUFFIX=legacy + fi + sleep 1 + if [[ ! -z $(which pip) && $(pip list --local 2>&1 | grep -v DEPRECATION | grep -c docker-compose) == 1 ]]; then + true + #prevent breaking a working docker-compose installed with pip + elif [[ $(curl -sL -w "%{http_code}" https://www.servercow.de/docker-compose/latest.php?vers=${DC_DL_SUFFIX} -o /dev/null) == "200" ]]; then + LATEST_COMPOSE=$(curl -#L https://www.servercow.de/docker-compose/latest.php) + COMPOSE_VERSION=$(docker-compose version --short) + if [[ "$LATEST_COMPOSE" != "$COMPOSE_VERSION" ]]; then + COMPOSE_PATH=$(which docker-compose) + if [[ -w ${COMPOSE_PATH} ]]; then + curl -#L https://github.com/docker/compose/releases/download/v${LATEST_COMPOSE}/docker-compose-$(uname -s)-$(uname -m) > $COMPOSE_PATH + chmod +x $COMPOSE_PATH + else + echo -e "\e[33mWARNING: $COMPOSE_PATH is not writable, but new version $LATEST_COMPOSE is available (installed: $COMPOSE_VERSION)\e[0m" + return 1 + fi + fi + else + echo -e "\e[33mCannot determine latest docker-compose version, skipping...\e[0m" + return 1 + fi +fi +} + while (($#)); do case "${1}" in --check|-c) @@ -256,6 +279,9 @@ while (($#)); do echo -e "\e[32mRunning in forced mode...\e[0m" FORCE=y ;; + --no-update-compose) + NO_UPDATE_COMPOSE=y + ;; --skip-ping-check) SKIP_PING_CHECK=y ;; @@ -265,6 +291,7 @@ while (($#)); do -c|--check - Check for updates and exit (exit codes => 0: update available, 3: no updates) --ours - Use merge strategy option "ours" to solve conflicts in favor of non-mailcow code (local changes over remote changes), not recommended! --gc - Run garbage collector to delete old image tags + --no-update-compose - Do not update docker-compose --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). @@ -281,7 +308,7 @@ source mailcow.conf DOTS=${MAILCOW_HOSTNAME//[^.]}; if [ ${#DOTS} -lt 2 ]; then echo "MAILCOW_HOSTNAME (${MAILCOW_HOSTNAME}) is not a FQDN!" - echo "Please change it to a FQDN and run ${COMPOSE_COMMAND} down followed by ${COMPOSE_COMMAND} up -d" + echo "Please change it to a FQDN and run docker-compose down followed by docker-compose up -d" exit 1 fi @@ -571,6 +598,7 @@ echo -e "\e[32mChecking for newer update script...\e[0m" SHA1_1=$(sha1sum update.sh) git fetch origin #${BRANCH} git checkout origin/${BRANCH} update.sh +git checkout origin/${BRANCH} docker-compose.yml SHA1_2=$(sha1sum update.sh) if [[ ${SHA1_1} != ${SHA1_2} ]]; then echo "update.sh changed, please run this script again, exiting." @@ -594,14 +622,16 @@ if [ ! $FORCE ]; then migrate_docker_nat fi +update_compose + echo -e "\e[32mValidating docker-compose stack configuration...\e[0m" -if ! ${COMPOSE_COMMAND} config -q; then +if ! docker-compose config -q; then echo -e "\e[31m\nOh no, something went wrong. Please check the error message above.\e[0m" exit 1 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) +MAILCOW_BRIDGE=$(docker-compose 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) @@ -621,8 +651,8 @@ prefetch_images echo -e "\e[32mStopping mailcow...\e[0m" sleep 2 -MAILCOW_CONTAINERS=($(${COMPOSE_COMMAND} ps -q)) -${COMPOSE_COMMAND} down +MAILCOW_CONTAINERS=($(docker-compose ps -q)) +docker-compose down echo -e "\e[32mChecking for remaining containers...\e[0m" sleep 2 for container in "${MAILCOW_CONTAINERS[@]}"; do @@ -659,16 +689,13 @@ elif [[ ${MERGE_RETURN} == 1 ]]; then elif [[ ${MERGE_RETURN} != 0 ]]; then echo -e "\e[31m\nOh no, something went wrong. Please check the error message above.\e[0m" echo - echo "Run ${COMPOSE_COMMAND} up -d to restart your stack without updates or try again after fixing the mentioned errors." + echo "Run docker-compose up -d to restart your stack without updates or try again after fixing the mentioned errors." exit 1 fi -echo -e "\e[33mNot fetching latest docker-compose, please check for updates manually!\e[0m" -sleep 3 - echo -e "\e[32mFetching new images, if any...\e[0m" sleep 2 -${COMPOSE_COMMAND} pull +docker-compose pull # Fix missing SSL, does not overwrite existing files [[ ! -d data/assets/ssl ]] && mkdir -p data/assets/ssl @@ -723,11 +750,11 @@ else fi if [[ ${SKIP_START} == "y" ]]; then - echo -e "\e[33mNot starting mailcow, please run \"${COMPOSE_COMMAND} up -d --remove-orphans\" to start mailcow.\e[0m" + echo -e "\e[33mNot starting mailcow, please run \"docker-compose up -d --remove-orphans\" to start mailcow.\e[0m" else echo -e "\e[32mStarting mailcow...\e[0m" sleep 2 - ${COMPOSE_COMMAND} up -d --remove-orphans + docker-compose up -d --remove-orphans fi echo -e "\e[32mCollecting garbage...\e[0m" @@ -738,8 +765,8 @@ if [ -f "${SCRIPT_DIR}/post_update_hook.sh" ]; then bash "${SCRIPT_DIR}/post_update_hook.sh" fi -#echo "In case you encounter any problem, hard-reset to a state before updating mailcow:" -#echo -#git reflog --color=always | grep "Before update on " -#echo -#echo "Use \"git reset --hard hash-on-the-left\" and run ${COMPOSE_COMMAND} up -d afterwards." \ No newline at end of file +# echo "In case you encounter any problem, hard-reset to a state before updating mailcow:" +# echo +# git reflog --color=always | grep "Before update on " +# echo +# echo "Use \"git reset --hard hash-on-the-left\" and run docker-compose up -d afterwards." \ No newline at end of file From a139eb9bce925e66a99639efd4b1027e020ac26a Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 16 Jun 2022 12:38:06 +0200 Subject: [PATCH 36/52] Readded Dual Stack availability of WebUI (default) --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index e3b08637..a563df91 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -377,8 +377,8 @@ services: - ./data/conf/rspamd/meta_exporter:/meta_exporter:ro,z - sogo-web-vol-1:/usr/lib/GNUstep/SOGo/ ports: - - "${HTTPS_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}" - - "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:${HTTP_PORT:-80}" + - "${HTTPS_BIND:-}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}" + - "${HTTP_BIND:-}:${HTTP_PORT:-80}:${HTTP_PORT:-80}" restart: always networks: mailcow-network: From 36e4ee7738570f7598f227a864bf852e58ac789b Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 16 Jun 2022 12:41:49 +0200 Subject: [PATCH 37/52] Before update on 2022-06-16_12_41_05 --- docker-compose.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index a563df91..753901aa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -580,36 +580,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 872fa072131873a8482bbedf049caf186f3a0ea1 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 16 Jun 2022 12:49:17 +0200 Subject: [PATCH 38/52] Restore docker-compose check in scripts --- generate_config.sh | 21 +--------- helper-scripts/_cold-standby.sh | 57 +--------------------------- helper-scripts/backup_and_restore.sh | 26 +++---------- 3 files changed, 9 insertions(+), 95 deletions(-) diff --git a/generate_config.sh b/generate_config.sh index 800f0b53..de285178 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -25,29 +25,10 @@ if cp --help 2>&1 | grep -q -i "busybox"; then exit 1 fi -for bin in openssl curl docker git awk sha1sum; do +for bin in openssl curl docker docker-compose git awk sha1sum; do if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi done -echo "checking docker compose version..."; -if docker compose >/dev/null 2>&1; then - echo -e "\e[32mFound Compose v2!\e[0m" -elif docker-compose version --short | grep -m1 "^2" > /dev/null 2>&1; then - echo -e "\e[32mFound Compose v2!\e[0m" - COMPOSE_COMMAND="docker-compose" -elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then - echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" - echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - echo -e "\e[33mPlease consider a upgrade to Docker-Compose v2.\e[0m" - echo - echo - echo -e "\e[33mContinuing...\e[0m" - sleep 3 -else - echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" - exit 1 -fi - if [ -f mailcow.conf ]; then read -r -p "A config file exists and will be overwritten, are you sure you want to continue? [y/N] " response case $response in diff --git a/helper-scripts/_cold-standby.sh b/helper-scripts/_cold-standby.sh index 14200954..b71d85cd 100755 --- a/helper-scripts/_cold-standby.sh +++ b/helper-scripts/_cold-standby.sh @@ -77,33 +77,13 @@ function preflight_local_checks() { exit 1 fi - for bin in rsync docker grep cut; do + for bin in rsync docker docker-compose grep cut; do if [[ -z $(which ${bin}) ]]; then >&2 echo -e "\e[31mCannot find ${bin} in local PATH, exiting...\e[0m" exit 1 fi done - - echo "checking docker compose version..."; - if docker compose >/dev/null 2>&1; then - echo -e "\e[32mFound Compose v2 on local machine!\e[0m" - elif docker-compose version --short | grep -m1 "^2" > /dev/null 2>&1; then - echo -e "\e[32mFound Compose v2!\e[0m" - COMPOSE_COMMAND="docker-compose" - elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then - echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" - echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - echo -e "\e[33mPlease consider a upgrade to Docker-Compose v2.\e[0m" - echo - echo - echo -e "\e[33mContinuing...\e[0m" - sleep 3 - else - echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" - exit 1 - fi - if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo -e "\e[31mBusyBox grep detected on local system, please install GNU grep\e[0m" exit 1 @@ -131,7 +111,7 @@ function preflight_remote_checks() { exit 1 fi - for bin in rsync docker; do + for bin in rsync docker docker-compose; do if ! ssh -o StrictHostKeyChecking=no \ -i "${REMOTE_SSH_KEY}" \ ${REMOTE_SSH_HOST} \ @@ -141,39 +121,6 @@ function preflight_remote_checks() { exit 1 fi done - - echo "checking docker compose version on remote..."; - if ssh -q -o StrictHostKeyChecking=no \ - -i "${REMOTE_SSH_KEY}" \ - ${REMOTE_SSH_HOST} \ - -p ${REMOTE_SSH_PORT} \ - -t 'docker compose' >/dev/null 2>&1; then - echo -e "\e[32mFound Compose v2 on remote!\e[0m" - COMPOSE_COMMAND="docker compose" - elif ssh -q -o StrictHostKeyChecking=no \ - -i "${REMOTE_SSH_KEY}" \ - ${REMOTE_SSH_HOST} \ - -p ${REMOTE_SSH_PORT} \ - -t 'docker-compose version --short' | grep -m1 "^2" > /dev/null 2>&1; then - echo -e "\e[32mFound Compose v2!\e[0m" - COMPOSE_COMMAND="docker-compose" - elif ssh -q -o StrictHostKeyChecking=no \ - -i "${REMOTE_SSH_KEY}" \ - ${REMOTE_SSH_HOST} \ - -p ${REMOTE_SSH_PORT} \ - -t 'docker-compose version --short' | grep -m1 "^1" > /dev/null 2>&1; then - echo -e "\e[33mWARN: The remote is using Docker-Compose v1!\e[0m" - echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - echo -e "\e[33mPlease consider a upgrade to Docker-Compose v2 on remote.\e[0m" - echo - echo - echo -e "\e[33mContinuing...\e[0m" - sleep 3 - COMPOSE_COMMAND="docker-compose" - else - echo -e "\e[31mCannot find Docker-Compose v1 or v2 on the Remote Machine! Please install Docker-Compose v2 on that and re-run the script.\e[0m" - exit 1 - fi } preflight_local_checks diff --git a/helper-scripts/backup_and_restore.sh b/helper-scripts/backup_and_restore.sh index 8136def3..b45fcb97 100755 --- a/helper-scripts/backup_and_restore.sh +++ b/helper-scripts/backup_and_restore.sh @@ -76,26 +76,12 @@ else CMPS_PRJ=$(echo ${COMPOSE_PROJECT_NAME} | tr -cd "[0-9A-Za-z-_]") fi -echo "checking docker compose version..."; -if docker compose >/dev/null 2>&1; then - echo -e "\e[32mFound Compose v2!\e[0m" - COMPOSE_COMMAND="docker compose" -elif docker-compose version --short | grep -m1 "^2" > /dev/null 2>&1; then - echo -e "\e[32mFound Compose v2!\e[0m" - COMPOSE_COMMAND="docker-compose" -elif docker-compose version --short | grep -m1 "^1" > /dev/null 2>&1; then - echo -e "\e[33mWARN: Your machine is using Docker-Compose v1!\e[0m" - echo -e "\e[33mmailcow will drop the Docker-Compose v1 Support in December 2022\e[0m" - echo -e "\e[33mPlease consider a upgrade to Docker-Compose v2.\e[0m" - echo - echo - echo -e "\e[33mContinuing...\e[0m" - sleep 3 - COMPOSE_COMMAND="docker-compose" -else - echo -e "\e[31mCannot find Docker-Compose v1 or v2 on your System. Please install Docker-Compose v2 and re-run the Script.\e[0m" - exit 1 -fi +for bin in docker docker-compose; do + if [[ -z $(which ${bin}) ]]; then + >&2 echo -e "\e[31mCannot find ${bin} in local PATH, exiting...\e[0m" + exit 1 + fi +done if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then >&2 echo -e "\e[31mBusyBox grep detected on local system, please install GNU grep\e[0m" From 89cea31475720a19c366fc31e620ff11525ec47b Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 16 Jun 2022 12:51:51 +0200 Subject: [PATCH 39/52] Revert "Before update on 2022-06-16_12_41_05" This reverts commit 36e4ee7738570f7598f227a864bf852e58ac789b. --- docker-compose.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 753901aa..a563df91 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -580,6 +580,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 6612b892b77c8a255580c3554eaca671dc169604 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 16 Jun 2022 12:56:54 +0200 Subject: [PATCH 40/52] Removed extra checkout line --- update.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/update.sh b/update.sh index 26a09785..c46751a5 100755 --- a/update.sh +++ b/update.sh @@ -597,8 +597,7 @@ fi echo -e "\e[32mChecking for newer update script...\e[0m" SHA1_1=$(sha1sum update.sh) git fetch origin #${BRANCH} -git checkout origin/${BRANCH} update.sh -git checkout origin/${BRANCH} docker-compose.yml +git checkout origin/${BRANCH} update.sh docker-compose.yml SHA1_2=$(sha1sum update.sh) if [[ ${SHA1_1} != ${SHA1_2} ]]; then echo "update.sh changed, please run this script again, exiting." From 499273dbb757a6420f8d352c8f1ac0a8323f454b Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 16 Jun 2022 13:50:44 +0200 Subject: [PATCH 41/52] Readded docker-compose check --- update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update.sh b/update.sh index c46751a5..3de7e561 100755 --- a/update.sh +++ b/update.sh @@ -40,7 +40,7 @@ PATH=$PATH:/opt/bin umask 0022 -for bin in curl docker git awk sha1sum; do +for bin in curl docker docker-compose git awk sha1sum; do if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi done From dd6b8c44a4e71b0d59e2d90573a2b8c667cbb403 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 16 Jun 2022 14:13:08 +0200 Subject: [PATCH 42/52] Added automatic docker-compose standalone installation --- update.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/update.sh b/update.sh index 3de7e561..dc47c3de 100755 --- a/update.sh +++ b/update.sh @@ -40,8 +40,20 @@ PATH=$PATH:/opt/bin umask 0022 -for bin in curl docker docker-compose git awk sha1sum; do - if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi +for bin in curl docker git awk sha1sum; do + if [[ -z $(which ${bin}) ]]; then + echo "Cannot find ${bin}, exiting..." + exit 1; + elif [[ -z $(which docker-compose) ]]; then + echo "Cannot find docker-compose Standalone. Installing..." + sleep 3 + if [[ -e /etc/alpine-release ]]; then + echo -e "\e[33mNot installing latest docker-compose, because you are using Alpine Linux without glibc support. Install docker-compose via apk!\e[0m" + exit 1 + fi + curl -#L https://github.com/docker/compose/releases/download/v$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose + chmod +x /usr/local/bin/docker-compose + fi done export LC_ALL=C From af9c3a8565a40ade25909e86a5da09c7ab34fd31 Mon Sep 17 00:00:00 2001 From: milkmaker Date: Sun, 19 Jun 2022 22:23:35 +0200 Subject: [PATCH 43/52] [Web] Updated lang.es.json [CI SKIP] (#4638) Co-authored-by: Daniel Castellanos Co-authored-by: Daniel Castellanos --- data/web/lang/lang.es.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/web/lang/lang.es.json b/data/web/lang/lang.es.json index 9a67c3c6..ba12202f 100644 --- a/data/web/lang/lang.es.json +++ b/data/web/lang/lang.es.json @@ -19,7 +19,8 @@ "syncjobs": "Trabajos de sincronización", "tls_policy": "Póliza de TLS", "unlimited_quota": "Cuota ilimitada para buzones", - "app_passwds": "Gestionar las contraseñas de aplicaciones" + "app_passwds": "Gestionar las contraseñas de aplicaciones", + "domain_desc": "Cambiar descripción del dominio" }, "add": { "activate_filter_warn": "Todos los demás filtros se desactivarán cuando este filtro se active.", From cd7715fa0e2779fecbf82a985c25e8e74603be25 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Mon, 20 Jun 2022 10:32:14 +0200 Subject: [PATCH 44/52] Restore docker-compose check in scripts --- helper-scripts/_cold-standby.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper-scripts/_cold-standby.sh b/helper-scripts/_cold-standby.sh index b71d85cd..7fc5a495 100755 --- a/helper-scripts/_cold-standby.sh +++ b/helper-scripts/_cold-standby.sh @@ -258,7 +258,7 @@ echo "OK" -i "${REMOTE_SSH_KEY}" \ ${REMOTE_SSH_HOST} \ -p ${REMOTE_SSH_PORT} \ - $COMPOSE_COMMAND -f "${SCRIPT_DIR}/../docker-compose.yml" pull --no-parallel --quiet 2>&1 ; then + docker-compose -f "${SCRIPT_DIR}/../docker-compose.yml" pull --no-parallel --quiet 2>&1 ; then >&2 echo -e "\e[31m[ERR]\e[0m - Could not pull images on remote" fi From d373164e13a14e058f82c9f1918a5612f375a9f9 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Mon, 20 Jun 2022 21:18:57 +0200 Subject: [PATCH 45/52] hotfix imapsync --- data/web/inc/init_db.inc.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index 88be5bca..1e53d4b8 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 = "20052022_0938"; + $db_version = "18062022_1153"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -440,7 +440,7 @@ function init_db_schema() { "spam_score" => "TINYINT(1) NOT NULL DEFAULT '1'", "spam_policy" => "TINYINT(1) NOT NULL DEFAULT '1'", "delimiter_action" => "TINYINT(1) NOT NULL DEFAULT '1'", - "syncjobs" => "TINYINT(1) NOT NULL DEFAULT '1'", + "syncjobs" => "TINYINT(1) NOT NULL DEFAULT '0'", "eas_reset" => "TINYINT(1) NOT NULL DEFAULT '1'", "sogo_profile_reset" => "TINYINT(1) NOT NULL DEFAULT '0'", "pushover" => "TINYINT(1) NOT NULL DEFAULT '1'", @@ -1228,8 +1228,17 @@ function init_db_schema() { } // Mitigate imapsync pipemess issue - $pdo->query("UPDATE `imapsync` SET `custom_params` = '' WHERE `custom_params` LIKE '%pipemess%' OR `custom_params` LIKE '%pipemes%';"); - + $pdo->query("UPDATE `imapsync` SET `custom_params` = '' + WHERE `custom_params` LIKE '%pipemess%' + OR custom_params LIKE '%skipmess%' + OR custom_params LIKE '%delete2foldersonly%' + OR custom_params LIKE '%delete2foldersbutnot%' + OR custom_params LIKE '%regexflag%' + OR custom_params LIKE '%pipemess%' + OR custom_params LIKE '%regextrans2%' + OR custom_params LIKE '%maxlinelengthcmd%';"); + + // Migrate webauthn tfa $stmt = $pdo->query("ALTER TABLE `tfa` MODIFY COLUMN `authmech` ENUM('yubi_otp', 'u2f', 'hotp', 'totp', 'webauthn')"); From 452daf5d5eca1ba95d7e5befadf0ca8ab0dcab12 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 23 Jun 2022 08:55:06 +0200 Subject: [PATCH 46/52] Restored docker-compose Command --- 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 b45fcb97..d6f11ca8 100755 --- a/helper-scripts/backup_and_restore.sh +++ b/helper-scripts/backup_and_restore.sh @@ -239,7 +239,7 @@ function restore() { continue else echo "Stopping mailcow..." - ${COMPOSE_COMMAND} -f ${COMPOSE_FILE} --env-file ${ENV_FILE} down + docker-compose -f ${COMPOSE_FILE} --env-file ${ENV_FILE} down fi #docker stop $(docker ps -qf name=mysql-mailcow) if [[ -d "${RESTORE_LOCATION}/mysql" ]]; then @@ -277,7 +277,7 @@ function restore() { sed -i --follow-symlinks "/DBROOT/c\DBROOT=${DBROOT}" ${SCRIPT_DIR}/../mailcow.conf source ${SCRIPT_DIR}/../mailcow.conf echo "Starting mailcow..." - ${COMPOSE_COMMAND} -f ${COMPOSE_FILE} --env-file ${ENV_FILE} up -d + docker-compose -f ${COMPOSE_FILE} --env-file ${ENV_FILE} up -d #docker start $(docker ps -aqf name=mysql-mailcow) fi ;; From db7d7ea288ca1ea85959890616dd1a694452acd2 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 23 Jun 2022 10:05:09 +0200 Subject: [PATCH 47/52] Added override NGINX Port Removal --- update.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/update.sh b/update.sh index dc47c3de..104ef38e 100755 --- a/update.sh +++ b/update.sh @@ -209,6 +209,26 @@ migrate_docker_nat() { fi } +remove_obsolete_nginx_ports() { + # Removing obsolete docker-compose.override.yml + if [ -s docker-compose.override.* ]; then + if cat docker-compose.override.* | grep nginx-mailcow > /dev/null 2>&1; then + if cat docker-compose.override.* | grep -w [::] > /dev/null 2>&1; then + if cat docker-compose.override.* | grep -w 80:80 > /dev/null 2>&1 && cat docker-compose.override.* | grep -w 443:443 > /dev/null 2>&1 ; then + sed -i '/nginx-mailcow:$/,/^$/d' docker-compose.override.* + if [[ "$(cat docker-compose.override.yml | sed '/^\s*$/d' | wc -l)" == "2" ]]; then + mv docker-compose.override.yml docker-compose.override.yml_backup + echo -e "\e[31mRemoved obsolete NGINX IPv6 Bind from override File.\e[0m" + elif [[ "$(cat docker-compose.override.yaml | sed '/^\s*$/d' | wc -l)" == "2" ]]; then + mv docker-compose.override.yaml docker-compose.override.yaml_backup + echo -e "\e[31mRemoved obsolete NGINX IPv6 Bind from override File.\e[0m" + fi + fi + fi + fi + fi +} + update_compose(){ if [[ ${NO_UPDATE_COMPOSE} == "y" ]]; then echo -e "\e[33mNot fetching latest docker-compose, please check for updates manually!\e[0m" @@ -635,6 +655,8 @@ fi update_compose +remove_obsolete_nginx_ports + echo -e "\e[32mValidating docker-compose stack configuration...\e[0m" if ! docker-compose config -q; then echo -e "\e[31m\nOh no, something went wrong. Please check the error message above.\e[0m" From 092890b6abca7e195d0742fbf644119c57439a70 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 23 Jun 2022 10:23:48 +0200 Subject: [PATCH 48/52] Changed message in nginx-port removal function --- update.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/update.sh b/update.sh index 104ef38e..9836b927 100755 --- a/update.sh +++ b/update.sh @@ -216,12 +216,13 @@ remove_obsolete_nginx_ports() { if cat docker-compose.override.* | grep -w [::] > /dev/null 2>&1; then if cat docker-compose.override.* | grep -w 80:80 > /dev/null 2>&1 && cat docker-compose.override.* | grep -w 443:443 > /dev/null 2>&1 ; then sed -i '/nginx-mailcow:$/,/^$/d' docker-compose.override.* + echo -e "\e[32mRemoved obsolete NGINX IPv6 Bind from override File.\e[0m" if [[ "$(cat docker-compose.override.yml | sed '/^\s*$/d' | wc -l)" == "2" ]]; then mv docker-compose.override.yml docker-compose.override.yml_backup - echo -e "\e[31mRemoved obsolete NGINX IPv6 Bind from override File.\e[0m" + echo -e "\e[31mdocker-compose.override.yml is empty. Renamed it to ensure mailcow is startable.\e[0m" elif [[ "$(cat docker-compose.override.yaml | sed '/^\s*$/d' | wc -l)" == "2" ]]; then mv docker-compose.override.yaml docker-compose.override.yaml_backup - echo -e "\e[31mRemoved obsolete NGINX IPv6 Bind from override File.\e[0m" + echo -e "\e[31mdocker-compose.override.yml is empty. Renamed it to ensure mailcow is startable.\e[0m" fi fi fi From 263baa81c07b2a3546ee6301d58eba511a8747fc Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 23 Jun 2022 10:55:12 +0200 Subject: [PATCH 49/52] Improved .yml and .yaml check for Port Removal --- update.sh | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/update.sh b/update.sh index 9836b927..714541aa 100755 --- a/update.sh +++ b/update.sh @@ -211,23 +211,22 @@ migrate_docker_nat() { remove_obsolete_nginx_ports() { # Removing obsolete docker-compose.override.yml - if [ -s docker-compose.override.* ]; then - if cat docker-compose.override.* | grep nginx-mailcow > /dev/null 2>&1; then - if cat docker-compose.override.* | grep -w [::] > /dev/null 2>&1; then - if cat docker-compose.override.* | grep -w 80:80 > /dev/null 2>&1 && cat docker-compose.override.* | grep -w 443:443 > /dev/null 2>&1 ; then - sed -i '/nginx-mailcow:$/,/^$/d' docker-compose.override.* - echo -e "\e[32mRemoved obsolete NGINX IPv6 Bind from override File.\e[0m" - if [[ "$(cat docker-compose.override.yml | sed '/^\s*$/d' | wc -l)" == "2" ]]; then - mv docker-compose.override.yml docker-compose.override.yml_backup - echo -e "\e[31mdocker-compose.override.yml is empty. Renamed it to ensure mailcow is startable.\e[0m" - elif [[ "$(cat docker-compose.override.yaml | sed '/^\s*$/d' | wc -l)" == "2" ]]; then - mv docker-compose.override.yaml docker-compose.override.yaml_backup - echo -e "\e[31mdocker-compose.override.yml is empty. Renamed it to ensure mailcow is startable.\e[0m" + for override in docker-compose.override.yml docker-compose.override.yaml; do + if [ -s $override ] ; then + if cat $override | grep nginx-mailcow > /dev/null 2>&1; then + if cat $override | grep -w [::] > /dev/null 2>&1; then + if cat $override | grep -w 80:80 > /dev/null 2>&1 && cat $override | grep -w 443:443 > /dev/null 2>&1 ; then + sed -i '/nginx-mailcow:$/,/^$/d' $override + echo -e "\e[33mRemoved obsolete NGINX IPv6 Bind from override File.\e[0m" + if [[ "$(cat $override | sed '/^\s*$/d' | wc -l)" == "2" ]]; then + mv $override ${override}_backup + echo -e "\e[31m${override} is empty. Renamed it to ensure mailcow is startable.\e[0m" fi fi fi fi - fi + fi + done } update_compose(){ From c1c7167acef67aed73b7af388a88cb75868dd500 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Thu, 23 Jun 2022 15:41:48 +0200 Subject: [PATCH 50/52] Added auto correction of composev1 Binds in compose.yml --- update.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/update.sh b/update.sh index 714541aa..6d91becc 100755 --- a/update.sh +++ b/update.sh @@ -629,7 +629,7 @@ fi echo -e "\e[32mChecking for newer update script...\e[0m" SHA1_1=$(sha1sum update.sh) git fetch origin #${BRANCH} -git checkout origin/${BRANCH} update.sh docker-compose.yml +git checkout origin/${BRANCH} update.sh SHA1_2=$(sha1sum update.sh) if [[ ${SHA1_1} != ${SHA1_2} ]]; then echo "update.sh changed, please run this script again, exiting." @@ -658,6 +658,8 @@ update_compose remove_obsolete_nginx_ports echo -e "\e[32mValidating docker-compose stack configuration...\e[0m" +sed -i 's/HTTPS_BIND:-:/HTTPS_BIND:-/g' docker-compose.yml +sed -i 's/HTTP_BIND:-:/HTTP_BIND:-/g' docker-compose.yml if ! docker-compose config -q; then echo -e "\e[31m\nOh no, something went wrong. Please check the error message above.\e[0m" exit 1 From a835419168394bcbefdafb03de50fa9e6187717a Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Thu, 23 Jun 2022 18:36:54 +0200 Subject: [PATCH 51/52] fix imapsync --- data/web/inc/functions.mailbox.inc.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index d6a07eab..788b207f 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -339,6 +339,8 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { // validate custom params foreach (explode(' -', $custom_params) as $param){ + if(empty($param)) continue; + if (str_contains($param, ' ')) { // bad char $_SESSION['return'][] = array( @@ -1792,6 +1794,8 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { // validate custom params foreach (explode(' -', $custom_params) as $param){ + if(empty($param)) continue; + if (str_contains($param, ' ')) { // bad char $_SESSION['return'][] = array( From 33eb2c8801c86952ec8e89a4c041c55849ae2485 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Fri, 24 Jun 2022 23:10:00 +0200 Subject: [PATCH 52/52] Improved [::] Section check + included prior override backup --- update.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/update.sh b/update.sh index 6d91becc..ea283eb2 100755 --- a/update.sh +++ b/update.sh @@ -214,10 +214,14 @@ remove_obsolete_nginx_ports() { for override in docker-compose.override.yml docker-compose.override.yaml; do if [ -s $override ] ; then if cat $override | grep nginx-mailcow > /dev/null 2>&1; then - if cat $override | grep -w [::] > /dev/null 2>&1; then + if cat $override | grep -E '(\[::])' > /dev/null 2>&1; then if cat $override | grep -w 80:80 > /dev/null 2>&1 && cat $override | grep -w 443:443 > /dev/null 2>&1 ; then + echo -e "\e[33mBacking up ${override} to preserve custom changes...\e[0m" + echo -e "\e[33m!!! Manual Merge needed (if other overrides are set) !!!\e[0m" + sleep 3 + cp $override ${override}_backup sed -i '/nginx-mailcow:$/,/^$/d' $override - echo -e "\e[33mRemoved obsolete NGINX IPv6 Bind from override File.\e[0m" + echo -e "\e[33mRemoved obsolete NGINX IPv6 Bind from original override File.\e[0m" if [[ "$(cat $override | sed '/^\s*$/d' | wc -l)" == "2" ]]; then mv $override ${override}_backup echo -e "\e[31m${override} is empty. Renamed it to ensure mailcow is startable.\e[0m"