diff --git a/docker-compose.yml b/docker-compose.yml index c1ce6b9..36e1e2e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,10 +4,14 @@ services: build: postfix restart: unless-stopped env_file: - - environment + - ssl.env + - postfix.env volumes: - ./aliases:/etc/postfix/virtual + - ./domains:/etc/postfix/domains - /var/lib/acme/:/var/lib/acme/:ro + - /var/lib/docker-volumes/mail/queue/:/var/spool/postfix + - postfix-dh:/etc/postfix/dh-params networks: mail: depends_on: @@ -24,9 +28,11 @@ services: build: dovecot restart: unless-stopped env_file: - - environment + - ssl.env + - ldap.env + - dovecot.env volumes: - - /var/lib/docker-volumes/mail/vmail/:/srv/vmail/ + - /var/lib/docker-volumes/mail/vmail/:/var/vmail/ - /var/lib/acme/:/var/lib/acme/:ro networks: mail: @@ -36,7 +42,7 @@ services: image: runningman84/rainloop restart: unless-stopped env_file: - - environment + - rainloop.env volumes: - /var/lib/docker-volumes/mail/rainloop/:/var/www/html/data networks: @@ -47,3 +53,6 @@ networks: auth: external: true name: auth_auth + +volumes: + postfix-dh: {} diff --git a/dovecot.env b/dovecot.env new file mode 100644 index 0000000..e69de29 diff --git a/dovecot/10-logging.conf b/dovecot/10-logging.conf index 212f501..df28b41 100644 --- a/dovecot/10-logging.conf +++ b/dovecot/10-logging.conf @@ -1,6 +1,6 @@ log_path = /dev/stdout -auth_verbose = yes +#auth_verbose = yes plugin { # Events to log. Also available: flag_change append diff --git a/dovecot/Dockerfile b/dovecot/Dockerfile index 45a6187..a519886 100644 --- a/dovecot/Dockerfile +++ b/dovecot/Dockerfile @@ -5,10 +5,12 @@ RUN apk add --no-cache \ dovecot-ldap RUN sed -i 's/#!include auth-ldap.conf.ext/!include auth-ldap.conf.ext/' /etc/dovecot/conf.d/10-auth.conf \ - && sed -i 's/!include auth-passwdfile.conf.ext/#!include auth-passwdfile.conf.ext/' /etc/dovecot/conf.d/10-auth.conf + && sed -i 's/!include auth-passwdfile.conf.ext/#!include auth-passwdfile.conf.ext/' /etc/dovecot/conf.d/10-auth.conf \ + && sed -i 's/#first_valid_uid = .*/first_valid_uid = 100/g' /etc/dovecot/conf.d/10-mail.conf \ + && sed -i 's/#last = .*/last = 100/g' /etc/dovecot/conf.d/10-mail.conf -RUN mkdir /ssl-params-cache/ \ - && ln -s /ssl-params-cache/ssl-parameters.dat /var/lib/dovecot/ssl-parameters.dat +RUN addgroup -S vmail \ + && adduser -S -g '' -H -D -h /var/vmail vmail vmail COPY 10-master.conf /etc/dovecot/conf.d/10-master.conf COPY 10-logging.conf /etc/dovecot/conf.d/10-logging.conf @@ -17,6 +19,6 @@ COPY entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] -VOLUME "/ssl-params-cache/" +VOLUME ["/var/vmail"] EXPOSE 24 100 143 diff --git a/dovecot/auth-ldap.conf.ext b/dovecot/auth-ldap.conf.ext index 72acb21..e37e23e 100644 --- a/dovecot/auth-ldap.conf.ext +++ b/dovecot/auth-ldap.conf.ext @@ -2,7 +2,8 @@ passdb { driver = ldap args = /etc/dovecot/dovecot-ldap.conf.ext } + userdb { - driver = ldap - args = /etc/dovecot/dovecot-ldap-userdb.conf.ext + driver = static + args = uid=vmail gid=vmail home=/var/vmail/%d/%n mail=maildir:/var/vmail/%d/%n/Maildir } diff --git a/dovecot/entrypoint.sh b/dovecot/entrypoint.sh index db65d68..6a7fd82 100755 --- a/dovecot/entrypoint.sh +++ b/dovecot/entrypoint.sh @@ -1,15 +1,15 @@ #!/bin/ash -cat > /etc/dovecot/dovecot-ldap.conf.ext << LDAP +cat >> /etc/dovecot/dovecot-ldap.conf.ext << DOVECOTLDAP hosts = $LDAP_SERVER -auth_bind = yes base = $LDAP_BASE +auth_bind = yes user_filter = (&(objectClass=posixAccount)(mail=%u)) pass_filter = (&(objectClass=posixAccount)(mail=%u)) -user_attrs = \ - =home=/var/vmail/%d/%u, \ - =mail=maildir:/var/vmail/%d/%u/Maildir -LDAP +#user_attrs = \ +# =home=/var/vmail/%d/%n, \ +# =mail=maildir:/var/vmail/%d/%n/Maildir +DOVECOTLDAP cat > /etc/dovecot/conf.d/10-ssl.conf << SSL ssl = required @@ -19,6 +19,6 @@ ssl_key = <$TLS_KEY ssl_dh_parameters_length = 2048 SSL -ln -s /etc/dovecot/dovecot-ldap.conf.ext /etc/dovecot/dovecot-ldap-userdb.conf.ext +echo -e "auth_verbose=yes\nauth_debug=yes\nauth_debug_passwords=yes" >> /etc/dovecot/dovecot.conf -dovecot -F +exec dovecot -F diff --git a/environment.dist b/environment.dist deleted file mode 100644 index 5ff3d1e..0000000 --- a/environment.dist +++ /dev/null @@ -1,11 +0,0 @@ -HOSTNAME=mail.example.com -VIRTUAL_HOSTS=example.com example.net -RELAYS= -TLS_CERT=/path/to/cert -TLS_CHAIN=/path/to/chain -TLS_FULLCHAIN=/path/to/certandchain -TLS_KEY=/path/to/key -LDAP_SERVER=ldap -LDAP_BASE=dc=ldap,dc=example,dc=com -RAINLOOP_ADMIN_LOGIN=admin -RAINLOOP_ADMIN_PASSWORD=password diff --git a/ldap.env b/ldap.env new file mode 100644 index 0000000..fec1a04 --- /dev/null +++ b/ldap.env @@ -0,0 +1,2 @@ +LDAP_SERVER=ldap +LDAP_BASE=dc=ldap,dc=sbruder,dc=de diff --git a/postfix.env b/postfix.env new file mode 100644 index 0000000..541d82c --- /dev/null +++ b/postfix.env @@ -0,0 +1,5 @@ +MYHOSTNAME=mail.kegelschiene.com +MYDOMAIN=mail.kegelschiene.com +MAIL_NAME="sbrudermail" + +MESSAGE_SIZE_LIMIT=15360000 diff --git a/postfix/Dockerfile b/postfix/Dockerfile index 83f9634..c002eba 100644 --- a/postfix/Dockerfile +++ b/postfix/Dockerfile @@ -1,19 +1,54 @@ FROM alpine:latest RUN apk add --no-cache \ - supervisor \ - rsyslog \ - ca-certificates \ - postfix \ - openssl + supervisor \ + rsyslog \ + ca-certificates \ + postfix \ + postfix-pcre \ + openssl + +RUN echo '' > /etc/postfix/main.cf \ + && postconf -e myorigin='$myhostname' \ + && postconf -e mynetworks='127.0.0.0/8 [::1]/128' \ + && postconf -e smtpd_relay_restrictions='permit_sasl_authenticated, permit_mynetworks, reject_unlisted_sender, reject_unlisted_recipient, reject_unknown_sender_domain, reject_unknown_recipient_domain, reject_invalid_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unauth_destination, reject_unknown_hostname' \ + && postconf -e smtpd_recipient_restrictions='check_recipient_access hash:/etc/postfix/access_recipient, check_sender_access hash:/etc/postfix/access_sender, check_helo_access hash:/etc/postfix/access_helo, check_client_access cidr:/etc/postfix/access_client, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unknown_sender_domain, reject_unknown_recipient_domain, permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, reject_rbl_client zen.spamhaus.org, reject_rbl_client ix.dnsbl.manitu.net, check_policy_service inet:postgrey:25 reject_unverified_recipient, permit' \ + && postconf -e recipient_delimiter='+' \ + && postconf -e smtpd_banner='$myhostname ESMTP $mail_name' \ + && postconf -e smtpd_use_tls='yes' \ + && postconf -e smtpd_tls_security_level='may' \ + && postconf -e smtpd_tls_auth_only='yes' \ + && postconf -e smtpd_tls_loglevel='1' \ + && postconf -e smtpd_tls_mandatory_protocols='!SSLv2,!SSLv3,!TLSv1,!TLSv1.1' \ + && postconf -e smtpd_tls_protocols='!SSLv2,!SSLv3,!TLSv1,!TLSv1.1' \ + && postconf -e smtpd_tls_mandatory_ciphers='medium' \ + && postconf -e tls_medium_cipherlist='AES128+EECDH:AES128+EDH' \ + && postconf -e smtpd_tls_dh1024_param_file='/etc/postfix/dh-params/2048.pem' \ + && postconf -e smtpd_tls_dh512_param_file='/etc/postfix/dh-params/512.pem' \ + && postconf -e smtpd_tls_eecdh_grade='strong' \ + && postconf -e tls_preempt_cipherlist='yes' \ + && postconf -e smtpd_sasl_auth_enable='yes' \ + && postconf -e smtpd_sasl_type='dovecot' \ + && postconf -e smtpd_sasl_path='inet:dovecot:100' \ + && postconf -e virtual_transport='lmtp:[dovecot]' \ + && postconf -e virtual_alias_maps='hash:/etc/postfix/virtual' \ + && postconf -e virtual_mailbox_domains='/etc/postfix/domains' \ + && postconf -e smtp_tls_security_level='may' \ + && postconf -e disable_vrfy_command='yes' \ + && postconf -e enable_long_queue_ids='yes' \ + && postconf -e strict_rfc821_envelopes='yes' + +# && postconf -e smtpd_recipient_restrictions='permit_sasl_authenticated, permit_mynetworks, reject_unlisted_sender, reject_unlisted_recipient, reject_unknown_sender_domain, reject_unknown_recipient_domain, reject_invalid_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unauth_destination, reject_unknown_hostname' \ + +COPY master.cf /etc/postfix/master.cf +COPY smtp_header_checks /etc/postfix/smtp_header_checks COPY postfix.sh /postfix.sh COPY supervisord.conf /etc/supervisord.conf ENTRYPOINT ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"] -VOLUME "/etc/postfix/dh-params/" +VOLUME ["/etc/postfix/dh-params/"] +VOLUME ["/var/spool/postfix"] EXPOSE 25 587 - -# Noch submission machen diff --git a/postfix/master.cf b/postfix/master.cf new file mode 100644 index 0000000..459170b --- /dev/null +++ b/postfix/master.cf @@ -0,0 +1,34 @@ +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (no) (never) (100) +# ========================================================================== + +smtp inet n - n - - smtpd +submission inet n - n - - smtpd + -o cleanup_service_name=subcleanup +pickup unix n - n 60 1 pickup +cleanup unix n - n - 0 cleanup +qmgr unix n - n 300 1 qmgr +tlsmgr unix - - n 1000? 1 tlsmgr +rewrite unix - - n - - trivial-rewrite +bounce unix - - n - 0 bounce +defer unix - - n - 0 bounce +trace unix - - n - 0 bounce +verify unix - - n - 1 verify +flush unix n - n 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - n - - smtp +relay unix - - n - - smtp +showq unix n - n - - showq +error unix - - n - - error +retry unix - - n - - error +discard unix - - n - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - n - - lmtp +anvil unix - - n - 1 anvil +scache unix - - n - 1 scache + +subcleanup unix n - n - 0 cleanup + -o header_checks=pcre:/etc/postfix/smtp_header_checks diff --git a/postfix/postfix.sh b/postfix/postfix.sh index 195fd64..d311c62 100755 --- a/postfix/postfix.sh +++ b/postfix/postfix.sh @@ -1,73 +1,27 @@ #!/bin/sh -cat > /etc/postfix/main.cf << MAINCF -# FQDN of system !reverse DNS! -myhostname = $HOSTNAME +[ -e /etc/postfix/dh-params/512.pem ] || openssl gendh -out /etc/postfix/dh-params/512.pem -2 512 +[ -e /etc/postfix/dh-params/2048.pem ] || openssl gendh -out /etc/postfix/dh-params/2048.pem -2 2048 -# aliases -virtual_alias_maps = hash:/etc/postfix/virtual +postconf -e myhostname="$MYHOSTNAME" +postconf -e mydomain="$MYDOMAIN" +postconf -e mail_name="$MAIL_NAME" -recipient_delimiter = + +postconf -e message_size_limit="$MESSAGE_SIZE_LIMIT" -smtpd_relay_restictions = - -smtpd_recipient_restrictions = -# white/blacklists - check_recipient_access hash:/etc/postfix/access_recipient - check_sender_access hash:/etc/postfix/access_sender, - check_helo_access hash:/etc/postfix/access_helo, - check_client_access cidr:/etc/postfix/access_client, -# deny mails for nonexistend recipients - reject_non_fqdn_sender, - reject_non_fqdn_recipient, - reject_unknown_sender_domain, - reject_unknown_recipient_domain, -# allow mails of our users - permit_sasl_authenticated, - permit_mynetworks, -# deny mails to external destinations - reject_unauth_destination, -# check against RBL - reject_rbl_client zen.spamhaus.org, - reject_rbl_client ix.dnsbl.manitu.net, -# check greylisting - check_policy_service inet:postgrey:25 -# check if the user exists in dovecot - reject_unverified_recipient, -# let it out - permit - -smtpd_sasl_auth_enable = yes -smtpd_sasl_path= inet:dovecot:100 -smtpd_sasl_type = dovecot - -# out -smtp_tls_security_level = may - -# in -smtpd_tls_security_level = may -smtpd_tls_cert_file = $TLS_CERT -smtpd_tls_CAfile = $TLS_CHAIN -smtpd_tls_key_file = $TLS_KEY - -smtpd_tls_dh1024_param_file = /etc/postfix/dh-params/2048.pem -smtpd_tls_dh512_param_file = /etc/postfix/dh-params/512.pem -smtpd_tls_eecdh_grade = strong -tls_preempt_cipherlist = yes - -smtpd_tls_auth_only = yes - -# for lmtp relaying to dovecot -relay_domains = hash:/etc/postfix/relay_domains -MAINCF - -[ -e /etc/postfix/relay_domains ] && rm /etc/postfix/relay_domains -for virtual_host in $VIRTUAL_HOSTS;do - echo "$virtual_host lmtp:[dovecot]" >> /etc/postfix/relay_domains -done -postmap /etc/postfix/relay_domains - -[ -e /etc/postfix/dh_512.pem ] || openssl gendh -out /etc/postfix/dh-params/512.pem -2 512 -[ -e /etc/postfix/dh_2048.pem ] || openssl gendh -out /etc/postfix/dh-params/2048.pem -2 2048 +postconf -e smtpd_tls_key_file="$TLS_KEY" +postconf -e smtpd_tls_cert_file="$TLS_FULLCHAIN" postmap /etc/postfix/virtual -/usr/lib/postfix/master -c /etc/postfix -d +postmap /etc/postfix/domains + +# is mounted, so no default structure +( + cd /var/spool/postfix + chown postfix:postfix . + for dir in active bounce corrupt defer deferred flush hold incoming maildrop pid private public saved trace; do + mkdir -p $dir + chown postfix:postfix $dir + done +) + +exec /usr/lib/postfix/master -c /etc/postfix -d diff --git a/postfix/smtp_header_checks b/postfix/smtp_header_checks new file mode 100644 index 0000000..1fd088a --- /dev/null +++ b/postfix/smtp_header_checks @@ -0,0 +1,5 @@ +/^\s*(Received: from)[^\n]*(.*)/ REPLACE $1 [127.0.0.1] (localhost [127.0.0.1])$2 +/^\s*User-Agent/ IGNORE +/^\s*X-Enigmail/ IGNORE +/^\s*X-Mailer/ IGNORE +/^\s*X-Originating-IP/ IGNORE diff --git a/rainloop.env b/rainloop.env new file mode 100644 index 0000000..a7c04ba --- /dev/null +++ b/rainloop.env @@ -0,0 +1,2 @@ +RAINLOOP_ADMIN_LOGIN=ibims1admin +RAINLOOP_ADMIN_PASSWORD=Oong7Shohg5caebi diff --git a/ssl.env b/ssl.env new file mode 100644 index 0000000..0c431f8 --- /dev/null +++ b/ssl.env @@ -0,0 +1,2 @@ +TLS_FULLCHAIN=/var/lib/acme/live/mail.kegelschiene.com/fullchain +TLS_KEY=/var/lib/acme/live/mail.kegelschiene.com/privkey