diff --git a/conf/postfix/main.cf b/conf/postfix/main.cf index 01af1b619..bf26f89c6 100644 --- a/conf/postfix/main.cf +++ b/conf/postfix/main.cf @@ -211,3 +211,11 @@ smtp_sasl_security_options = noanonymous # where to find sasl_passwd smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd {% endif %} + +{% if backup_mx_domains != "" %} +# Backup MX (secondary MX) +relay_domains = $mydestination {{backup_mx_domains}} +relay_recipient_maps = hash:/etc/postfix/relay_recipients +maximal_queue_lifetime = 20d +{% endif %} + diff --git a/conf/ssh/sshd_config b/conf/ssh/sshd_config index 4a239d2ad..c340e451f 100644 --- a/conf/ssh/sshd_config +++ b/conf/ssh/sshd_config @@ -84,7 +84,7 @@ Subsystem sftp internal-sftp # Apply following instructions to user with sftp perm only Match Group sftp.main,!ssh.main - ForceCommand internal-sftp + ForceCommand internal-sftp -u 0002 # We can't restrict to /home/%u because the chroot base must be owned by root # So we chroot only on /home # See https://serverfault.com/questions/584986/bad-ownership-or-modes-for-chroot-directory-component @@ -97,7 +97,7 @@ Match Group sftp.main,!ssh.main PermitUserRC no Match Group sftp.app,!ssh.app - ForceCommand internal-sftp + ForceCommand internal-sftp -u 0002 ChrootDirectory %h AllowTcpForwarding no AllowStreamLocalForwarding no diff --git a/hooks/conf_regen/19-postfix b/hooks/conf_regen/19-postfix index d6ddcb5ee..2e829055a 100755 --- a/hooks/conf_regen/19-postfix +++ b/hooks/conf_regen/19-postfix @@ -45,6 +45,21 @@ do_pre_regen() { cat <<<"[${relay_host}]:${relay_port} ${relay_user}:${relay_password}" >${postfix_dir}/sasl_passwd fi + + # Use this postfix server as a backup MX + export backup_mx_domains="$(yunohost settings get 'email.smtp.smtp_backup_mx_domains' | sed "s/,/ /g")" + export backup_mx_emails="$(yunohost settings get 'email.smtp.smtp_backup_mx_emails_whitelisted' | sed "s/,/ /g")" + rm -f ${postfix_dir}/relay_recipients + touch ${postfix_dir}/relay_recipients + if [ -n "${backup_mx_domains}" ] && [ -n "${backup_mx_emails}" ] + then + for mail in ${backup_mx_emails} + do + echo "$mail OK" >> ${postfix_dir}/relay_recipients + done + postmap ${postfix_dir}/relay_recipients + fi + export main_domain export domain_list="$(yunohost domain list --features mail_in mail_out --output-as json | jq -r ".domains[]" | tr '\n' ' ')" ynh_render_template "main.cf" "${postfix_dir}/main.cf" @@ -78,6 +93,11 @@ do_post_regen() { postmap /etc/postfix/sasl_passwd fi + if [ -e /etc/postfix/relay_recipients ]; then + chmod 750 /etc/postfix/relay_recipients* + chown postfix:root /etc/postfix/relay_recipients* + fi + postmap -F hash:/etc/postfix/sni python3 -c 'from yunohost.app import regen_mail_app_user_config_for_dovecot_and_postfix as r; r(only="postfix")' diff --git a/locales/en.json b/locales/en.json index f1e08bbe7..71a961919 100644 --- a/locales/en.json +++ b/locales/en.json @@ -456,6 +456,10 @@ "global_settings_setting_security_experimental_enabled_help": "Enable experimental security features (don't enable this if you don't know what you're doing!)", "global_settings_setting_smtp_allow_ipv6": "Allow IPv6", "global_settings_setting_smtp_allow_ipv6_help": "Allow the use of IPv6 to receive and send mail", + "global_settings_setting_smtp_backup_mx_domains": "Domains to act as secondary MX for", + "global_settings_setting_smtp_backup_mx_domains_help": "Allow this server to act as a backup *secondary* MX domain for the listed domain. This means that if the main MX for the domain is not reachable (for example because of an outage), mails will still be sent to this server, which will keep them during a maximum of 20 days and try to relay them to the real destination once it goes back up. Several domains can be provided, separated by commas.", + "global_settings_setting_smtp_backup_mx_emails_whitelisted": "SMTP backup MX emails whitelist", + "global_settings_setting_smtp_backup_mx_emails_whitelisted_help": "When acting as a secondary MX, the exhaustive list of allowed recipient's email addresses must be provided (otherwise mails will be refused and discarded). Several entries can be provided, separated by commas.", "global_settings_setting_smtp_relay_enabled": "Enable SMTP relay", "global_settings_setting_smtp_relay_enabled_help": "Enable the SMTP relay to use in order to send mail instead of this yunohost instance. Useful if you are in one of this situation: your 25 port is blocked by your ISP or VPS provider, you have a residential IP listed on DUHL, you are not able to configure reverse DNS or this server is not directly exposed on the internet and you want use an other one to send mails.", "global_settings_setting_smtp_relay_host": "SMTP relay host", diff --git a/locales/eu.json b/locales/eu.json index 665ed374d..fb3d4d9a1 100644 --- a/locales/eu.json +++ b/locales/eu.json @@ -804,4 +804,4 @@ "migration_0027_modified_files": "Ondorengo fitxategiak eskuz moldatu direla antzeman da eta litekeena da bertsio-berritzeak gainean idaztea: {manually_modified_files}", "migration_0027_not_enough_free_space": "/var/-en erabilgarri dagoen espazioa oso txikia da! Gutxienez GB 1 izan beharko zenuke erabilgarri migrazioari ekiteko.", "migration_0027_patching_sources_list": "sources.lists fitxategia petatxatzen…" -} +} \ No newline at end of file diff --git a/locales/fr.json b/locales/fr.json index 8a7f9ae4e..ce1a50cc2 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -806,4 +806,4 @@ "migration_0027_still_on_bullseye_after_main_upgrade": "Quelque chose s'est mal passé lors de la mise à jour du système, il semble que celui-ci soit toujours sous Debian Bullseye.", "migration_0027_system_not_fully_up_to_date": "Votre système n'est pas complètement à jour. Veuillez effectuer une mise à jour classique avant de procéder à la migration vers Bookworm.", "migration_0027_yunohost_upgrade": "Démarrage de la mise à jour du cœur de YunoHost…" -} +} \ No newline at end of file diff --git a/locales/gl.json b/locales/gl.json index dc7e0bfdf..7f718efb5 100644 --- a/locales/gl.json +++ b/locales/gl.json @@ -804,4 +804,4 @@ "migration_0027_not_enough_free_space": "Hai moi pouco espazo en /var/! Deberías ter polo menos 1GB libre para realizar a migración.", "migration_0027_patch_yunohost_conflicts": "Aplicando a solución para resolver o problema conflictivo…", "migration_0027_system_not_fully_up_to_date": "O teu sistema non está totalmente actualizado. Fai unha actualización corrente antes de iniciar a migración a Bookworm." -} +} \ No newline at end of file diff --git a/locales/id.json b/locales/id.json index 878005f4f..69b43c241 100644 --- a/locales/id.json +++ b/locales/id.json @@ -804,4 +804,4 @@ "update_apt_cache_warning": "Ada yang tidak sesuai saat memperbarui cache APT (manajer paket Debian). Berikut ini adalah kumpulan baris source.list, yang mungkin membantu mengidentifikasi baris yang bermasalah:\n{sourceslist}", "user_import_missing_columns": "Kehilangan kolom berikut: {columns}", "user_import_nothing_to_do": "Tidak ada pengguna yang perlu diimpor" -} +} \ No newline at end of file diff --git a/locales/ru.json b/locales/ru.json index f00405844..ac5a70025 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -360,4 +360,4 @@ "apps_failed_to_upgrade": "Не удалось обновить данные приложения:{apps}", "apps_failed_to_upgrade_line": "\n * {app_id} (чтобы увидеть соответствующий журнал, выполните «yunohost log show {operation_logger_name}»)", "ask_admin_fullname": "Полное имя администратора" -} +} \ No newline at end of file diff --git a/locales/sk.json b/locales/sk.json index 2586b5930..1568108d9 100644 --- a/locales/sk.json +++ b/locales/sk.json @@ -280,4 +280,4 @@ "domain_config_xmpp": "Krátke správy (XMPP)", "log_app_makedefault": "Nastaviť '{}' ako predvolenú aplikáciu", "domain_config_cert_renew_help": "Certifikát bude automaticky obnovený po 15 dňoch platnosti. Ak chcete, môžete ho obnoviť aj ručne. (Neodporúča sa)." -} +} \ No newline at end of file diff --git a/locales/tr.json b/locales/tr.json index f9351acff..d8a53da94 100644 --- a/locales/tr.json +++ b/locales/tr.json @@ -32,4 +32,4 @@ "app_change_url_identical_domains": "('{domain}{path}') Eski ve yeni alan adının veya URL adresler aynı.Şu anda yapacak bir şey bulunmuyor.", "app_corrupt_source": "YunoHost, {app} için '{source_id}' ({url}) adresinden indirebildi, ancak varlık olması gereken yapılandırmalarla eşleşmiyor. Bu, sunucunuzda geçici bir ağ arızası meydana geldiği veya varlığın bir şekilde yayın yapılan veri sağlacıyısı (veya kötü niyetli bir kişi?) tarafından değiştirildiği ve YunoHost yapımcılarının araştırması ve belki de bu değişikliği dikkate almak için uygulama bildirimini güncellemesi gerektiği anlamına gelebilir.\n Beklenen sha256 sağlama toplamı: {expected_sha256}\n İndirilen sha256 sağlama toplamı: {computed_sha256}\n İndirilen dosya boyutu: {size}", "app_failed_to_upgrade_but_continue": "{failed_app} uygulaması yükseltilirken başarısız oldu. Sıradaki güncellemeler devam ediyor. Konu ile ilgili hata kayıtlarını görüntülemek için 'yunohost log show {operation_logger_name}' komutunu çalıştırın" -} +} \ No newline at end of file diff --git a/share/config_global.toml b/share/config_global.toml index 40b71ab19..d836e50d5 100644 --- a/share/config_global.toml +++ b/share/config_global.toml @@ -107,7 +107,7 @@ name = "Email" [email.pop3.pop3_enabled] type = "boolean" default = false - + [email.smtp] name = "SMTP" [email.smtp.smtp_allow_ipv6] @@ -117,7 +117,7 @@ name = "Email" [email.smtp.smtp_relay_enabled] type = "boolean" default = false - + [email.smtp.smtp_relay_host] type = "string" default = "" @@ -134,7 +134,7 @@ name = "Email" default = "" optional = true visible="smtp_relay_enabled" - + [email.smtp.smtp_relay_password] type = "password" default = "" @@ -142,6 +142,17 @@ name = "Email" visible="smtp_relay_enabled" help = "" # This is empty string on purpose, otherwise the core automatically set the 'good_practice_admin_password' string here which is not relevant, because the admin is not actually "choosing" the password ... + [email.smtp.smtp_backup_mx_domains] + type = "string" + default = "" + optional = true + + [email.smtp.smtp_backup_mx_emails_whitelisted] + type = "string" + default = "" + optional = true + visible = "smtp_backup_mx_domains" + [misc] name = "Other" [misc.portal] diff --git a/src/settings.py b/src/settings.py index abe1a8f13..4f42183be 100644 --- a/src/settings.py +++ b/src/settings.py @@ -335,6 +335,8 @@ def reconfigure_ssh_and_fail2ban(setting_name, old_value, new_value): @post_change_hook("smtp_relay_port") @post_change_hook("smtp_relay_user") @post_change_hook("smtp_relay_password") +@post_change_hook("smtp_backup_mx_domains") +@post_change_hook("smtp_backup_mx_emails_whitelisted") @post_change_hook("postfix_compatibility") def reconfigure_postfix(setting_name, old_value, new_value): if old_value != new_value: