Commit 86295f82 authored by Vincent Pelletier's avatar Vincent Pelletier

erp5: Rework postfix integration.

Add support for "hosts" aliasing in Zope instances.
Add support for SASL relayhost with mandatory TLS encryption.
Add mandatory TSL + SASL authentication, to not be an open relay.
Wrap postfix commands with proper environment instead of symlink +
source-able script.
Add ipv6 listening support (untested).
Drop non-required main.cf configuration options.
Make postifx instance optional (requires postmaster address to be
provided).
Document and rework smtp-related parameters.
Expose an userhosts hostname for smtp server.
Add diversion support (solution to "prod clone sent mails to real customer").
Use etc/run rather than etc/service, for consistency (if it needs to be
changed, it must be changed for all software types).
Hook into syslog and setup local syslog daemon, with logrotate integration.
Update TODO entries.
parent 48672684
{
"$schema": "http://json-schema.org/draft-04/schema#",
"extends": "./schema-definitions.json#",
"required": ["tcpv4-port"],
"properties": {
"tcpv4-port": {
"allOf": [{
"$ref": "#/definitions/tcpv4port"
}, {
"description": "Start allocating ports at this value, going upward"
}]
},
"postmaster": {
"description": "Mail address to send technical mails to. Non-empty value required for smptd relay service to be deployed. Values will be put in alias-dict as 'postmaster' key (alias-dict takes precedence)",
"default": "",
"type": "string"
},
"alias-dict": {
"description": "Mail alias support",
"default": {},
"patternProperties": {
".*": {
"description": "List of addresses alias expands to",
"type": "array"
}
},
"type": "object"
},
"relay": {
"description": "Forward outgoing mails to a specific relay. If enabled, relay must support TLS-encrypted SASL authentication.",
"dependencies": {
"host": ["sasl-credential"]
},
"properties": {
"host": {
"description": "Host name or address of relay, with optional port (ex: '[example.com]:submissionu'). Enclosing hostname with [] prevents MX lookup.",
"type": "string"
},
"sasl-credential": {
"description": "SASL credential, in the login:password form",
"type": "string"
}
},
"default": {},
"type": "object"
},
"divert": {
"description": "Intercept all mails and send them to given addresses instead of original recipient",
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
}
}
}
...@@ -6,7 +6,8 @@ General: ...@@ -6,7 +6,8 @@ General:
- resilience - resilience
- make mariadb user accounts accept connections only from relevant IPs - make mariadb user accounts accept connections only from relevant IPs
or make x509 mandatory (needs ZMySQLD*A support) or make x509 mandatory (needs ZMySQLD*A support)
- postfix - make postfix log inside partition
- document postfix parameters (only once it actually works)
Monitoring: Monitoring:
- daily slow-query digest - daily slow-query digest
......
...@@ -202,24 +202,29 @@ md5sum = 79f789360e71146486c82a7a10834bae ...@@ -202,24 +202,29 @@ md5sum = 79f789360e71146486c82a7a10834bae
[template-postfix] [template-postfix]
< = download-base < = download-base
filename = instance-postfix.cfg.in filename = instance-postfix.cfg.in
md5sum = a1b131b5bf6a749b0c853e9577f43cca md5sum = 90a017581116f14014a039d38ef36ffd
[template-postfix-master-cf] [template-postfix-master-cf]
< = download-base < = download-base
filename = postfix_master.cf.in filename = postfix_master.cf.in
md5sum = 67f06ed63c5d3fa47908a83071b76bd3 md5sum = 9ac81647368068a1a98a785d08074b43
[template-postfix-main-cf] [template-postfix-main-cf]
< = download-base < = download-base
filename = postfix_main.cf.in filename = postfix_main.cf.in
md5sum = b6f44d8507aa15d71fdff75bf3eeddb9 md5sum = d51897728755e14d8005344608098009
[template-postfix-aliases]
< = download-base
filename = postfix_aliases.in
md5sum = 0969fbb25b05c02ef3c2d437b2f4e1a0
[template] [template]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
# XXX: "template.cfg" is hardcoded in instanciation recipe # XXX: "template.cfg" is hardcoded in instanciation recipe
rendered = ${buildout:directory}/template.cfg rendered = ${buildout:directory}/template.cfg
template = ${:_profile_base_location_}/instance.cfg.in template = ${:_profile_base_location_}/instance.cfg.in
md5sum = 4b7ef360e34de488daab0d44973fd598 md5sum = 4d043c96d70b35d1fbbd8120d8edee7c
mode = 640 mode = 640
context = context =
key mariadb_link_binary template-mariadb:link-binary key mariadb_link_binary template-mariadb:link-binary
...@@ -232,6 +237,7 @@ context = ...@@ -232,6 +237,7 @@ context =
key coreutils_location coreutils:location key coreutils_location coreutils:location
key cups_location cups:location key cups_location cups:location
key curl_location curl:location key curl_location curl:location
key cyrus_sasl_location cyrus-sasl:location
key dash_location dash:location key dash_location dash:location
key dbus_glib_location dbus-glib:location key dbus_glib_location dbus-glib:location
key dbus_location dbus:location key dbus_location dbus:location
...@@ -286,6 +292,7 @@ context = ...@@ -286,6 +292,7 @@ context =
key template_mariadb_initial_setup template-mariadb-initial-setup:target key template_mariadb_initial_setup template-mariadb-initial-setup:target
key template_my_cnf template-my-cnf:target key template_my_cnf template-my-cnf:target
key template_postfix template-postfix:target key template_postfix template-postfix:target
key template_postfix_aliases template-postfix-aliases:target
key template_postfix_main_cf template-postfix-main-cf:target key template_postfix_main_cf template-postfix-main-cf:target
key template_postfix_master_cf template-postfix-master-cf:target key template_postfix_master_cf template-postfix-master-cf:target
key template_runzope_userhosts_preloaded template-runzope-userhosts-preloaded:target key template_runzope_userhosts_preloaded template-runzope-userhosts-preloaded:target
...@@ -301,7 +308,7 @@ context = ...@@ -301,7 +308,7 @@ context =
[template-erp5] [template-erp5]
<= download-base <= download-base
filename = instance-erp5.cfg.in filename = instance-erp5.cfg.in
md5sum = bb951a205def0235f3c041045abd7801 md5sum = 60cdf98d996f220d66daa11452c3f4bf
[template-zeo] [template-zeo]
<= download-base <= download-base
...@@ -311,7 +318,7 @@ md5sum = 9670cf63099e2c520017a23defff51a4 ...@@ -311,7 +318,7 @@ md5sum = 9670cf63099e2c520017a23defff51a4
[template-zope] [template-zope]
<= download-base <= download-base
filename = instance-zope.cfg.in filename = instance-zope.cfg.in
md5sum = 74f2fbd7d653b0e6cfe29efcd1042ace md5sum = 995257c4d08365db7ac0d1b40936ef8b
link-binary = link-binary =
${aspell:location}/bin/aspell ${aspell:location}/bin/aspell
${dmtx-utils:location}/bin/dmtxwrite ${dmtx-utils:location}/bin/dmtxwrite
......
...@@ -4,11 +4,12 @@ ...@@ -4,11 +4,12 @@
{% set site_id = slapparameter_dict.get('site-id', 'erp5') -%} {% set site_id = slapparameter_dict.get('site-id', 'erp5') -%}
{% set inituser_login = slapparameter_dict.get('inituser-login', 'zope') -%} {% set inituser_login = slapparameter_dict.get('inituser-login', 'zope') -%}
{% set publish_dict = {'site-id': site_id, 'inituser-login': inituser_login} -%} {% set publish_dict = {'site-id': site_id, 'inituser-login': inituser_login} -%}
{% set has_posftix = slapparameter_dict.get('smtp', {}).get('postmaster') -%}
[request-common] [request-common]
<= request-common-base <= request-common-base
config-use-ipv6 = {{ dumps(slapparameter_dict.get('use-ipv6', False)) }} config-use-ipv6 = {{ dumps(slapparameter_dict.get('use-ipv6', False)) }}
{% macro request(name, software_type, config_key, config, ret={'url': True}) -%} {% macro request(name, software_type, config_key, config, ret={'url': True}, key_config={}) -%}
{% do config.update(slapparameter_dict.get(config_key, {})) -%} {% do config.update(slapparameter_dict.get(config_key, {})) -%}
{% set section = 'request-' ~ name -%} {% set section = 'request-' ~ name -%}
[{{ section }}] [{{ section }}]
...@@ -25,13 +26,22 @@ return = {{ ' '.join(ret) }} ...@@ -25,13 +26,22 @@ return = {{ ' '.join(ret) }}
{% for k, v in config.iteritems() -%} {% for k, v in config.iteritems() -%}
config-{{ k }} = {{ dumps(v) }} config-{{ k }} = {{ dumps(v) }}
{% endfor -%} {% endfor -%}
{% for k, v in key_config.iteritems() -%}
config-{{ k }} = {{ '${' ~ v ~ '}' }}
{% endfor -%}
{% endmacro -%} {% endmacro -%}
{{ request('memcached-persistent', 'kumofs', 'kumofs', {'tcpv4-port': 2000}) }} {{ request('memcached-persistent', 'kumofs', 'kumofs', {'tcpv4-port': 2000}) }}
{{ request('memcached-volatile', 'kumofs', 'memcached', {'tcpv4-port': 2010, 'ram-storage-size': 64}) }} {{ request('memcached-volatile', 'kumofs', 'memcached', {'tcpv4-port': 2010, 'ram-storage-size': 64}) }}
{{ request('cloudooo', 'cloudooo', 'cloudooo', {'tcpv4-port': 2020}) }} {{ request('cloudooo', 'cloudooo', 'cloudooo', {'tcpv4-port': 2020}) }}
{{ request('mariadb', 'mariadb', 'mariadb', {'tcpv4-port': 2099}, {'database-list': True, 'test-database-list': True}) }} {{ request('mariadb', 'mariadb', 'mariadb', {'tcpv4-port': 2099}, {'database-list': True, 'test-database-list': True}) }}
{{ request('postfix', 'postfix', 'postfix', {'tcpv4-port': 2025}) }} {% if has_posftix -%}
{{ request('smtp', 'postfix', 'smtp', {'tcpv4-port': 2025, 'smtpd-sasl-user': 'erp5@nowhere'}, key_config={'smtpd-sasl-password': 'publish-early:smtpd-sasl-password'}) }}
{%- else %}
[request-smtp]
# Placeholder smtp service URL
connection-url = smtp://127.0.0.2:0/
{%- endif %}
{# ZODB -#} {# ZODB -#}
{% set zodb_dict = {} -%} {% set zodb_dict = {} -%}
...@@ -66,6 +76,9 @@ recipe = slapos.cookbook:publish-early ...@@ -66,6 +76,9 @@ recipe = slapos.cookbook:publish-early
-init = -init =
inituser-password gen-password:passwd inituser-password gen-password:passwd
deadlock-debugger-password gen-deadlock-debugger-password:passwd deadlock-debugger-password gen-deadlock-debugger-password:passwd
{%- if has_posftix %}
smtpd-sasl-password gen-smtpd-sasl-password:passwd
{%- endif %}
{%- if neo %} {%- if neo %}
neo-cluster gen-neo-cluster:name neo-cluster gen-neo-cluster:name
{%- if neo[0] %} {%- if neo[0] %}
...@@ -94,6 +107,9 @@ storage-path = ...@@ -94,6 +107,9 @@ storage-path =
[gen-neo-cluster] [gen-neo-cluster]
name = neo-${gen-neo-cluster-base:passwd} name = neo-${gen-neo-cluster-base:passwd}
[gen-smtpd-sasl-password]
< = gen-password
[request-zope-base] [request-zope-base]
<= request-common <= request-common
return = return =
...@@ -113,7 +129,7 @@ config-memcached-url = ${request-memcached-volatile:connection-url} ...@@ -113,7 +129,7 @@ config-memcached-url = ${request-memcached-volatile:connection-url}
config-mysql-test-url-list = ${request-mariadb:connection-test-database-list} config-mysql-test-url-list = ${request-mariadb:connection-test-database-list}
config-mysql-url-list = ${request-mariadb:connection-database-list} config-mysql-url-list = ${request-mariadb:connection-database-list}
config-site-id = {{ dumps(site_id) }} config-site-id = {{ dumps(site_id) }}
config-smtp-url = {{ dumps(slapparameter_dict.get('smtp-url', 'smtp://localhost:25/')) }} config-smtp-url = ${request-smtp:connection-url}
config-timezone = {{ dumps(slapparameter_dict.get('timezone', 'UTC')) }} config-timezone = {{ dumps(slapparameter_dict.get('timezone', 'UTC')) }}
config-zodb-dict = {{ dumps(zodb_dict) }} config-zodb-dict = {{ dumps(zodb_dict) }}
{% for server_type, server_dict in storage_dict.iteritems() -%} {% for server_type, server_dict in storage_dict.iteritems() -%}
......
{% if software_type == slap_software_type -%}
{% set part_list = [] -%} {% set part_list = [] -%}
{% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%} {% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%}
{% set ipv4 = (ipv4_set | list)[0] -%} {% if slapparameter_dict['use-ipv6'] -%}
{% set ip = '[' ~ (ipv6_set | list)[0] ~ ']' -%}
{% else -%}
{% set ip = (ipv4_set | list)[0] -%}
{% endif -%}
{% set tcpv4_port = slapparameter_dict['tcpv4-port'] -%} {% set tcpv4_port = slapparameter_dict['tcpv4-port'] -%}
{% set relay = slapparameter_dict.get('relay', {}) -%}
[buildout] {% set divert = slapparameter_dict.get('divert', []) -%}
parts = {% set alias_dict = slapparameter_dict.get('alias-dict', {}) -%}
publish-postfix-connection-information {% do alias_dict.setdefault('postmaster', [slapparameter_dict['postmaster']]) -%}
postfix-main-cf {% set smtpd_sasl_user = slapparameter_dict['smtpd-sasl-user'] -%}
postfix-master-cf {% set smtpd_sasl_password = slapparameter_dict['smtpd-sasl-password'] -%}
postfix-symlinks-bin
postfix-symlinks-sbin [smtpd-password]
postfix-symlinks-libexec recipe = slapos.cookbook:generate.password
service-postfix-master storage-path =
sh-postfix-environment
newaliases [{{ section('publish') }}]
{{ part_list | join('\n ') }}
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
[publish-postfix-connection-information]
recipe = slapos.cookbook:publish.serialised recipe = slapos.cookbook:publish.serialised
url = smtp://${:ipv4}:${:port}/ url = {{ dumps('smtp://' ~ urllib.quote_plus(smtpd_sasl_user) ~ ':' ~ urllib.quote_plus(smtpd_sasl_password) ~ '@' ~ ip ~ ':' ~ tcpv4_port) }}
ipv4 = {{ ipv4 }}
port = ${postfix-master-cf-parameters:smtp_port}
[directory] [directory]
recipe = slapos.cookbook:mkdirectory recipe = slapos.cookbook:mkdirectory
etc = ${buildout:directory}/etc etc = ${buildout:directory}/etc
etc_postfix = ${:etc}/postfix
script = ${:etc}/run
service = ${:etc}/service
promise = ${:etc}/promise promise = ${:etc}/promise
etc-postfix = ${:etc}/postfix
etc-cyrus = ${:etc}/cyrus
run = ${:etc}/run
bin = ${buildout:directory}/bin
usr = ${buildout:directory}/usr usr = ${buildout:directory}/usr
usr_bin = ${:usr}/bin
usr_sbin = ${:usr}/sbin
var = ${buildout:directory}/var var = ${buildout:directory}/var
var_spool = ${:var}/spool var-lib = ${:var}/lib
var_spool_postfix = ${:var_spool}/postfix var-lib-postfix = ${:var-lib}/postfix
var_spool_postfix_active = ${:var_spool_postfix}/active var-spool = ${:var}/spool
var_spool_postfix_bounce = ${:var_spool_postfix}/bounce var-spool-postfix = ${:var-spool}/postfix
var_spool_postfix_corrupt = ${:var_spool_postfix}/corrupt # Not used at buildout level, presence needed by postfix.
var_spool_postfix_defer = ${:var_spool_postfix}/defer var-spool-postfix-active = ${:var-spool-postfix}/active
var_spool_postfix_deferred = ${:var_spool_postfix}/deferred var-spool-postfix-bounce = ${:var-spool-postfix}/bounce
var_spool_postfix_flush = ${:var_spool_postfix}/flush var-spool-postfix-corrupt = ${:var-spool-postfix}/corrupt
var_spool_postfix_hold = ${:var_spool_postfix}/hold var-spool-postfix-defer = ${:var-spool-postfix}/defer
var_spool_postfix_incoming = ${:var_spool_postfix}/incoming var-spool-postfix-deferred = ${:var-spool-postfix}/deferred
var_spool_postfix_maildrop = ${:var_spool_postfix}/maildrop var-spool-postfix-flush = ${:var-spool-postfix}/flush
var_spool_postfix_pid = ${:var_spool_postfix}/pid var-spool-postfix-hold = ${:var-spool-postfix}/hold
var_spool_postfix_private = ${:var_spool_postfix}/private var-spool-postfix-incoming = ${:var-spool-postfix}/incoming
var_spool_postfix_public = ${:var_spool_postfix}/public var-spool-postfix-maildrop = ${:var-spool-postfix}/maildrop
var_spool_postfix_saved = ${:var_spool_postfix}/saved var-spool-postfix-pid = ${:var-spool-postfix}/pid
var_spool_postfix_trace = ${:var_spool_postfix}/trace var-spool-postfix-private = ${:var-spool-postfix}/private
var_lib = ${:var}/lib var-spool-postfix-public = ${:var-spool-postfix}/public
var_mail = ${:var}/mail var-spool-postfix-saved = ${:var-spool-postfix}/saved
var_lib_postfix = ${:var_lib}/postfix var-spool-postfix-trace = ${:var-spool-postfix}/trace
[configuration]
smtp = {{ dumps(tcpv4_port) }}
inet-interfaces = {{ dumps(ip) }}
alias-dict = {{ dumps(alias_dict) }}
relayhost = {{ dumps(relay.get('host')) }}
relay-sasl-credential = {{ dumps(relay.get('sasl-credential')) }}
divert = {{ dumps(divert) }}
cyrus-sasldb = ${directory:etc-cyrus}/postfix.gdbm
[userinfo] [userinfo]
recipe = slapos.cookbook:userinfo recipe = slapos.cookbook:userinfo
[smtp-sasl-passwd]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:etc-postfix}/sasl_passwd
{% if relay -%}
template = inline:{{ "{{ host }} {{ sasl_credential }}" }}
{%- else -%}
template = inline:
{%- endif %}
context =
key host configuration:relayhost
key sasl_credential configuration:relay-sasl-credential
mode = 600
[postfix-main-cf] [{{ section('cyrus-smtpd-conf') }}]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
rendered = ${directory:etc_postfix}/main.cf rendered = ${directory:etc-cyrus}/smtpd.conf
template = {{ parameter_dict['template-postfix-main-cf'] }} template = inline:
pwcheck_method: auxprop
mech_list: PLAIN LOGIN
sasldb_path: {{ '{{ sasldb }}' }}
context = context =
raw queue_directory ${directory:var_spool_postfix} key sasldb configuration:cyrus-sasldb
raw command_directory ${directory:usr_sbin}
raw daemon_directory {{ parameter_dict['postfix-location'] }}/usr/libexec/postfix
raw data_directory ${directory:var_lib_postfix}
raw mail_owner ${userinfo:pw_name}
raw alias_database hash:${aliases:rendered}
raw alias_maps hash:${aliases:rendered}, nis:mail.aliases
raw mail_spool_directory ${directory:var_mail}
raw mydomain localdomain
raw myhostname test.localdomain
raw setgid_group ${userinfo:gr_name}
raw inet_interfaces {{ ipv4 }}
[{{ section('cyrus-smtpd-password') }}]
recipe = plone.recipe.command
stop-on-error = true
command =
rm -f '${configuration:cyrus-sasldb}' &&
echo '{{ smtpd_sasl_password }}' | '${wrapper-postfix-saslpasswd2:wrapper-path}' -pc '{{ smtpd_sasl_user }}'
update-command = ${:command}
[postfix-master-cf-parameters] [divert]
smtp_port = {{ tcpv4_port }} recipe = slapos.recipe.template:jinja2
rendered = ${directory:etc-postfix}/divert
{% if divert -%}
template = inline:{{ "/.*/ {{ ', '.join(divert) }}" }}
{%- else -%}
template = inline:
{%- endif %}
context =
key divert configuration:divert
[smtpd-ssl]
recipe = plone.recipe.command
stop-on-error = true
openssl = '{{ parameter_dict['openssl'] }}/bin/openssl'
cert = ${directory:etc-postfix}/smtpd.crt
key = ${directory:etc-postfix}/smtpd.pem
dh-512 = ${directory:etc-postfix}/dh512.pem
dh-2048 = ${directory:etc-postfix}/dh2048.pem
command =
${:openssl} dhparam -out '${:dh-512}' 512 &&
${:openssl} dhparam -out '${:dh-2048}' 2048 &&
${:update}
update =
${:openssl} req -newkey rsa -batch -new -x509 -days 3650 -nodes -keyout '${:key}' -out '${:cert}'
[postfix-master-cf] [{{ section('postfix-main-cf') }}]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:etc-postfix}/main.cf
template = {{ parameter_dict['template-postfix-main-cf'] }}
context =
key bin_directory directory:bin
key usr_directory directory:usr
key queue_directory directory:var-spool-postfix
key data_directory directory:var-lib-postfix
key spool_directory directory:var-spool
key mail_owner userinfo:pw-name
key setgid_group userinfo:gr-name
key inet_interfaces configuration:inet-interfaces
key relayhost configuration:relayhost
key sasl_passwd typed-paths:smtp-sasl-passwd
key aliases typed-paths:aliases
key divert typed-paths:divert
key cyrus_directory directory:etc-cyrus
key cert smtpd-ssl:cert
key key smtpd-ssl:key
key dh_512 smtpd-ssl:dh-512
key dh_2048 smtpd-ssl:dh-2048
[{{ section('postfix-master-cf') }}]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
rendered = ${directory:etc_postfix}/master.cf rendered = ${directory:etc-postfix}/master.cf
template = {{ parameter_dict['template-postfix-master-cf'] }} template = {{ parameter_dict['template-postfix-master-cf'] }}
context = section parameter_dict postfix-master-cf-parameters context = key smtp configuration:smtp
[aliases] [aliases]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
template = inline: template = {{ parameter_dict['template-postfix-aliases'] }}
# See http://www.postfix.org/aliases.5.html for format rendered = ${directory:etc-postfix}/aliases
rendered = ${directory:etc_postfix}/aliases context =
mode = 644 key alias_dict configuration:alias-dict
[typed-paths]
# Postfix-friendly rendering of file paths, prefixed with database type.
aliases = hash:${aliases:rendered}
smtp-sasl-passwd = hash:${smtp-sasl-passwd:rendered}
divert = pcre:${divert:rendered}
[newaliases] [{{ section('postalias-db') }}]
recipe = plone.recipe.command recipe = plone.recipe.command
stop-on-error = true stop-on-error = true
command = command = '${wrapper-postalias:wrapper-path}' '${typed-paths:aliases}' '${typed-paths:smtp-sasl-passwd}'
MAIL_CONFIG="${directory:etc_postfix}" {{ parameter_dict['postfix-location'] }}/usr/bin/newaliases
update-command = ${:command} update-command = ${:command}
[wrapper-postfix-saslpasswd2]
recipe = slapos.cookbook:wrapper
parameters-extra = true
command-line = '{{ parameter_dict['cyrus-sasl-location'] }}/sbin/saslpasswd2' -f '${configuration:cyrus-sasldb}'
wrapper-path = ${directory:bin}/saslpasswd2
[postfix-symlinks-bin] [base-wrapper]
recipe = slapos.cookbook:symbolic.link recipe = slapos.cookbook:wrapper
target-directory = ${directory:usr_bin} environment =
link-binary = MAIL_CONFIG=${directory:etc-postfix}
{{ parameter_dict['postfix-location'] }}/usr/bin/mailq SASL_CONF_PATH=${directory:etc-cyrus}
{{ parameter_dict['postfix-location'] }}/usr/bin/newaliases parameters-extra = true
[base-bin-wrapper]
[postfix-symlinks-sbin] < = base-wrapper
recipe = slapos.cookbook:symbolic.link command-line = ${:path}/${:basename}
target-directory = ${directory:usr_sbin} wrapper-path = ${directory:bin}/${:basename}
link-binary =
{{ parameter_dict['postfix-location'] }}/usr/sbin/postalias [base-bin-bin-wrapper]
{{ parameter_dict['postfix-location'] }}/usr/sbin/postcat < = base-bin-wrapper
{{ parameter_dict['postfix-location'] }}/usr/sbin/postconf path = {{ parameter_dict['postfix-location'] }}/usr/bin
{{ parameter_dict['postfix-location'] }}/usr/sbin/postdrop
{{ parameter_dict['postfix-location'] }}/usr/sbin/postfix [base-sbin-bin-wrapper]
{{ parameter_dict['postfix-location'] }}/usr/sbin/postkick < = base-bin-wrapper
{{ parameter_dict['postfix-location'] }}/usr/sbin/postlock path = {{ parameter_dict['postfix-location'] }}/usr/sbin
{{ parameter_dict['postfix-location'] }}/usr/sbin/postlog
{{ parameter_dict['postfix-location'] }}/usr/sbin/postmap {% for extend, basename_list in (
{{ parameter_dict['postfix-location'] }}/usr/sbin/postmulti (
{{ parameter_dict['postfix-location'] }}/usr/sbin/postqueue 'base-bin-bin-wrapper',
{{ parameter_dict['postfix-location'] }}/usr/sbin/postsuper (
{{ parameter_dict['postfix-location'] }}/usr/sbin/sendmail 'mailq',
'newaliases',
),
[postfix-symlinks-libexec] ),
(
'base-sbin-bin-wrapper',
(
'postalias',
'postcat',
'postconf',
'postdrop',
'postfix',
'postkick',
'postlock',
'postlog',
'postmap',
'postmulti',
'postqueue',
'postsuper',
'sendmail',
),
),
) %}
{% for basename in basename_list -%}
[{{ section('wrapper-' ~ basename) }}]
< = {{ extend }}
basename = {{ basename }}
{% endfor %}
{% endfor %}
[{{ section('postfix-symlinks-libexec') }}]
recipe = slapos.cookbook:symbolic.link recipe = slapos.cookbook:symbolic.link
target-directory = ${directory:usr} target-directory = ${directory:usr}
link-binary = link-binary =
{{ parameter_dict['postfix-location'] }}/usr/libexec {{ parameter_dict['postfix-location'] }}/usr/libexec
[{{ section('service-postfix-master') }}]
< = base-wrapper
command-line = ${directory:usr}/libexec/postfix/master
wrapper-path = ${directory:run}/postfix-master
[service-postfix-master] [{{ section('postfix-promise') }}]
recipe = slapos.cookbook:wrapper recipe = slapos.cookbook:check_port_listening
command-line = {{ parameter_dict['postfix-location'] }}/usr/libexec/postfix/master path = ${directory:promise}/postfix
wrapper-path = ${directory:service}/start-postfix-master hostname = {{ ip }}
environment = MAIL_CONFIG=${directory:etc_postfix} port = {{ tcpv4_port }}
[postfix-environment]
MAIL_CONFIG=${directory:etc_postfix}
[buildout]
[sh-postfix-environment] extends = {{ logrotate_cfg }}
recipe = slapos.recipe.template:jinja2 parts =
template = inline: {{ part_list | join('\n ') }}
export MAIL_CONFIG="${directory:etc_postfix}"
rendered = ${buildout:directory}/postfix-environment.sh
context =
section postfix_environment postfix-environment
mode = 755
{% endif %}
...@@ -114,6 +114,7 @@ ipv6 = {{ ipv6 }} ...@@ -114,6 +114,7 @@ ipv6 = {{ ipv6 }}
('erp5-memcached-volatile', slapparameter_dict['memcached-url']), ('erp5-memcached-volatile', slapparameter_dict['memcached-url']),
('erp5-memcached-persistent', slapparameter_dict['kumofs-url']), ('erp5-memcached-persistent', slapparameter_dict['kumofs-url']),
('erp5-cloudooo', slapparameter_dict['cloudooo-url']), ('erp5-cloudooo', slapparameter_dict['cloudooo-url']),
('erp5-smtp', slapparameter_dict['smtp-url']),
) -%} ) -%}
{% do hosts_dict.__setitem__( {% do hosts_dict.__setitem__(
alias, alias,
......
...@@ -45,7 +45,11 @@ extra-context = ...@@ -45,7 +45,11 @@ extra-context =
section parameter_dict dynamic-template-cloudooo-parameters section parameter_dict dynamic-template-cloudooo-parameters
[dynamic-template-postfix-parameters] [dynamic-template-postfix-parameters]
bin-directory = {{ bin_directory }}
cyrus-sasl-location = {{ cyrus_sasl_location }}
openssl = {{ openssl_location }}
postfix-location = {{ postfix_location }} postfix-location = {{ postfix_location }}
template-postfix-aliases = {{ template_postfix_aliases }}
template-postfix-main-cf = {{ template_postfix_main_cf }} template-postfix-main-cf = {{ template_postfix_main_cf }}
template-postfix-master-cf = {{ template_postfix_master_cf }} template-postfix-master-cf = {{ template_postfix_master_cf }}
...@@ -56,6 +60,7 @@ filename = instance-postfix.cfg ...@@ -56,6 +60,7 @@ filename = instance-postfix.cfg
extensions = jinja2.ext.do extensions = jinja2.ext.do
extra-context = extra-context =
section parameter_dict dynamic-template-postfix-parameters section parameter_dict dynamic-template-postfix-parameters
import urllib urllib
[dynamic-template-erp5-parameters] [dynamic-template-erp5-parameters]
local-bt5-repository = {{ local_bt5_repository }} local-bt5-repository = {{ local_bt5_repository }}
......
# See http://www.postfix.org/aliases.5.html for format
{% for name, alias_list in alias_dict.items() -%}
{{ name }}: {{ alias_list | join(', ') }}
{% endfor %}
# http://www.postfix.org/STANDARD_CONFIGURATION_README.html # http://www.postfix.org/STANDARD_CONFIGURATION_README.html
# http://www.postfix.org/postconf.5.html # http://www.postfix.org/postconf.5.html
queue_directory = {{ queue_directory }} queue_directory = {{ queue_directory }}
command_directory = {{ command_directory }} command_directory = {{ bin_directory }}
daemon_directory = {{ daemon_directory }} daemon_directory = {{ usr_directory }}/libexec/postfix
data_directory = {{ data_directory }} data_directory = {{ data_directory }}
mail_owner = {{ mail_owner }} mail_owner = {{ mail_owner }}
myhostname = {{ myhostname }} alias_maps = {{ aliases }}
mydomain = {{ mydomain }} alias_database = {{ aliases }}
unknown_local_recipient_reject_code = 550 mail_spool_directory = {{ spool_directory }}
alias_maps = {{ alias_maps }}
alias_database = {{ alias_database }}
mail_spool_directory = {{ mail_spool_directory }}
debug_peer_level = 2
sendmail_path = sendmail_path =
newaliases_path = newaliases_path =
mailq_path = mailq_path =
...@@ -20,5 +16,45 @@ html_directory = ...@@ -20,5 +16,45 @@ html_directory =
manpage_directory = manpage_directory =
sample_directory = sample_directory =
readme_directory = readme_directory =
inet_protocols = ipv4
inet_interfaces = {{ inet_interfaces }} inet_interfaces = {{ inet_interfaces }}
virtual_alias_maps = {{ divert }}
# Compared to default:
# - remove X-related variables, irrelevant for slapos, to be concise
# - add SASL_CONF_PATH to have per-partition cyrus-sasl configuration
import_environment =
MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ LANG=C
SASL_CONF_PATH
# Mandatory sasl auth over TLS
# XXX: no man-in-the-middle protection
smtpd_tls_cert_file = {{ cert }}
smtpd_tls_key_file = {{ key }}
smtpd_tls_dh512_param_file = {{ dh_512 }}
{#
Note: 1024 vs. 2048 is not a typo, but what is actually recommended in
postfix documentation
-#}
smtpd_tls_dh1024_param_file = {{ dh_2048 }}
smtpd_tls_security_level = encrypt
smtpd_sasl_auth_enable = yes
# Reject as many bogus cases as soon as possible, so errors are visible to ERP5
# developper rather than relying on bounces.
smtpd_recipient_restrictions =
reject_non_fqdn_recipient
reject_unknown_recipient_domain
permit_sasl_authenticated
reject
# Disable local delivery
local_transport = error
{% if relayhost -%}
relayhost = {{ relayhost }}
smtp_tls_security_level = encrypt
smtp_tls_session_cache_database = btree:{{ data_directory }}/smtp_scache
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = {{ sasl_passwd }}
smtp_sasl_tls_security_options = noanonymous
{%- endif %}
{% set smtp = parameter_dict['smtp_port'] -%} # http://www.postfix.org/master.5.html
# ========================================================================== # ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args # service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (100) # (yes) (yes) (yes) (never) (100)
# ========================================================================== # ==========================================================================
{{smtp}} inet n - n - - smtpd {{ smtp }} inet n - n - - smtpd
#submission inet n - n - - smtpd
pickup unix n - n 60 1 pickup pickup unix n - n 60 1 pickup
cleanup unix n - n - 0 cleanup cleanup unix n - n - 0 cleanup
qmgr unix n - n 300 1 qmgr qmgr unix n - n 300 1 qmgr
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment