diff --git a/data/hooks/conf_regen/19-postfix b/data/hooks/conf_regen/19-postfix index 68afe4bc9..67ca22991 100755 --- a/data/hooks/conf_regen/19-postfix +++ b/data/hooks/conf_regen/19-postfix @@ -23,7 +23,27 @@ do_pre_regen() { # Support different strategy for security configurations export compatibility="$(yunohost settings get 'security.postfix.compatibility')" + + # Add possibility to specify a relay + # Could be useful with some isp with no 25 port open or more complex setup + export relay_host="$(yunohost settings get 'smtp.relay.host')" + if [ ! -z "${relay_host}" ]; then + export relay_port="$(yunohost settings get 'smtp.relay.port')" + export relay_user="$(yunohost settings get 'smtp.relay.user')" + relay_password="$(yunohost settings get 'smtp.relay.password')" + + # Avoid to display "Relay account paswword" to other users + touch ${postfix_dir}/sasl_passwd + chmod o=--- ${postfix_dir}/sasl_passwd + # Avoid "postmap: warning: removing zero-length database file" + chown postfix ${pending_dir}/etc/postfix + chown postfix ${pending_dir}/etc/postfix/sasl_passwd + cat <<< "[${relay_host}]:${relay_port} ${relay_user}:${relay_password}" > ${postfix_dir}/sasl_passwd + postmap ${postfix_dir}/sasl_passwd + + + fi export main_domain export domain_list="$YNH_DOMAINS" ynh_render_template "main.cf" "${postfix_dir}/main.cf" @@ -47,6 +67,8 @@ do_pre_regen() { do_post_regen() { regen_conf_files=$1 + chmod o=--- /etc/postfix/sasl_passwd* + chown postfix /etc/postfix/sasl_passwd* [[ -z "$regen_conf_files" ]] \ || { service postfix restart && service postsrsd restart; } diff --git a/data/templates/postfix/main.cf b/data/templates/postfix/main.cf index cfadde356..61aa27211 100644 --- a/data/templates/postfix/main.cf +++ b/data/templates/postfix/main.cf @@ -53,8 +53,12 @@ smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtpd_tls_loglevel=1 # -- TLS for outgoing connections +{% if relay_host != "" %} +smtp_tls_security_level = encrypt +{% else %} # Use TLS if this is supported by the remote SMTP server, otherwise use plaintext. -smtp_tls_security_level=may +smtp_tls_security_level = may +{% endif %} smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtp_tls_exclude_ciphers = aNULL, MD5, DES, ADH, RC4, 3DES smtp_tls_mandatory_ciphers= high @@ -73,7 +77,11 @@ alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases mydomain = {{ main_domain }} mydestination = localhost +{% if relay_host == "" %} relayhost = +{% else %} +relayhost = [{{ relay_host }}]:{{ relay_port }} +{% endif %} mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 mailbox_command = procmail -a "$EXTENSION" mailbox_size_limit = 0 @@ -179,3 +187,13 @@ default_destination_rate_delay = 5s # So it's easly possible to scan a server to know which email adress is valid # and after to send spam disable_vrfy_command = yes + +{% if relay_user != "" %} +# Relay email through an other smtp account +# enable SASL authentication +smtp_sasl_auth_enable = yes +# disallow methods that allow anonymous authentication. +smtp_sasl_security_options = noanonymous +# where to find sasl_passwd +smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd +{% endif %} diff --git a/locales/en.json b/locales/en.json index 9fb31c663..340696054 100644 --- a/locales/en.json +++ b/locales/en.json @@ -321,6 +321,10 @@ "global_settings_unknown_setting_from_settings_file": "Unknown key in settings: '{setting_key:s}', discard it and save it in /etc/yunohost/settings-unknown.json", "global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Allow the use of (deprecated) DSA hostkey for the SSH daemon configuration", "global_settings_setting_smtp_allow_ipv6": "Allow the use of IPv6 to receive and send mail", + "global_settings_setting_smtp_relay_host": "SMTP relay host 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_port": "SMTP relay port", + "global_settings_setting_smtp_relay_user": "SMTP relay user account", + "global_settings_setting_smtp_relay_password": "SMTP relay host password", "global_settings_setting_backup_compress_tar_archives": "When creating new backups, compress the archives (.tar.gz) instead of uncompressed archives (.tar). N.B. : enabling this option means create lighter backup archives, but the initial backup procedure will be significantly longer and heavy on CPU.", "global_settings_unknown_type": "Unexpected situation, the setting {setting:s} appears to have the type {unknown_type:s} but it is not a type supported by the system.", "good_practices_about_admin_password": "You are now about to define a new administration password. The password should be at least 8 characters long—though it is good practice to use a longer password (i.e. a passphrase) and/or to use a variation of characters (uppercase, lowercase, digits and special characters).", diff --git a/src/yunohost/settings.py b/src/yunohost/settings.py index 0f8860529..db5f56b45 100644 --- a/src/yunohost/settings.py +++ b/src/yunohost/settings.py @@ -69,6 +69,10 @@ DEFAULTS = OrderedDict([ ("pop3.enabled", {"type": "bool", "default": False}), ("smtp.allow_ipv6", {"type": "bool", "default": True}), + ("smtp.relay.host", {"type": "string", "default": ""}), + ("smtp.relay.port", {"type": "int", "default": 587}), + ("smtp.relay.user", {"type": "string", "default": ""}), + ("smtp.relay.password", {"type": "string", "default": ""}), ("backup.compress_tar_archives", {"type": "bool", "default": False}), ]) @@ -330,6 +334,10 @@ def reconfigure_ssh(setting_name, old_value, new_value): @post_change_hook("smtp.allow_ipv6") +@post_change_hook("smtp.relay.host") +@post_change_hook("smtp.relay.port") +@post_change_hook("smtp.relay.user") +@post_change_hook("smtp.relay.password") @post_change_hook("security.postfix.compatibility") def reconfigure_postfix(setting_name, old_value, new_value): if old_value != new_value: