Merge ada945b492
into 5298271bfd
This commit is contained in:
commit
e1c75a27ec
|
@ -32,9 +32,11 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update -q --fix-missing && \
|
|||
opendmarc \
|
||||
p7zip \
|
||||
postfix \
|
||||
postfix-ldap \
|
||||
pyzor \
|
||||
razor \
|
||||
rsyslog \
|
||||
sasl2-bin \
|
||||
spamassassin \
|
||||
unzip \
|
||||
&& \
|
||||
|
|
25
Makefile
25
Makefile
|
@ -76,6 +76,31 @@ run:
|
|||
-e SSL_CERT_PATH=/tmp/docker-mailserver/letsencrypt/mail.my-domain.com/fullchain.pem \
|
||||
-e SSL_KEY_PATH=/tmp/docker-mailserver/letsencrypt/mail.my-domain.com/privkey.pem \
|
||||
-h mail.my-domain.com -t $(NAME)
|
||||
docker run -d --name mail_enable_ldap \
|
||||
-v "`pwd`/test/config":/tmp/docker-mailserver \
|
||||
-v "`pwd`/test":/tmp/docker-mailserver-test \
|
||||
-e LDAP=1 \
|
||||
-e SMTP_ONLY=1 \
|
||||
-h mail.my-domain.com -t $(NAME)
|
||||
docker run -d --name mail_enable_sasl_ldap \
|
||||
-v "`pwd`/test/config":/tmp/docker-mailserver \
|
||||
-v "`pwd`/test":/tmp/docker-mailserver-test \
|
||||
-e SASLAUTHD=1 \
|
||||
-e "SASL_LDAP_SERVER=192.168.0.100" \
|
||||
-e SASL_LDAP_PROTO= \
|
||||
-e "SASL_LDAP_BIND_DN=cn=Administrator,cn=Users,dc=my,dc=domain" \
|
||||
-e SASL_LDAP_PASSWORD=test \
|
||||
-e "SASL_LDAP_SEARCH_BASE=dc=my,dc=domain" \
|
||||
-e "SASL_LDAP_FILTER=(&(sAMAccountName=%U)(objectClass=person))" \
|
||||
-e SASL_MECHANISMS=ldap \
|
||||
-e SMTP_ONLY=1 \
|
||||
-h mail.my-domain.com -t $(NAME)
|
||||
docker run -d --name mail_enable_kopano \
|
||||
-v "`pwd`/test/config":/tmp/docker-mailserver \
|
||||
-v "`pwd`/test":/tmp/docker-mailserver-test \
|
||||
-e KOPANO=1 \
|
||||
-e SMTP_ONLY=1 \
|
||||
-h mail.my-domain.com -t $(NAME)
|
||||
# Wait for containers to fully start
|
||||
sleep 20
|
||||
|
||||
|
|
67
README.md
67
README.md
|
@ -17,6 +17,10 @@ Includes:
|
|||
- opendmarc
|
||||
- fail2ban
|
||||
- fetchmail
|
||||
- saslauthd
|
||||
- saslauthd ldap support
|
||||
- postfix ldap support
|
||||
- kopano support
|
||||
- basic [sieve support](https://github.com/tomav/docker-mailserver/wiki/Configure-Sieve-filters) using dovecot
|
||||
- [LetsEncrypt](https://letsencrypt.org/) and self-signed certificates
|
||||
- [integration tests](https://travis-ci.org/tomav/docker-mailserver)
|
||||
|
@ -147,7 +151,6 @@ Otherwise, `iptables` won't be able to ban IPs.
|
|||
- custom => Enables custom certificates
|
||||
- manual => Let's you manually specify locations of your SSL certificates for non-standard cases
|
||||
- self-signed => Enables self-signed certificates
|
||||
|
||||
Please read [the SSL page in the wiki](https://github.com/tomav/docker-mailserver/wiki/Configure-SSL) for more information.
|
||||
|
||||
##### PERMIT_DOCKER
|
||||
|
@ -157,6 +160,68 @@ Set different options for mynetworks option (can be overwrite in postfix-main.cf
|
|||
- host => Add docker host (ipv4 only)
|
||||
- network => Add all docker containers (ipv4 only)
|
||||
|
||||
##### SASL_MECHANISMS
|
||||
- empty => pam
|
||||
- ldap => authenticate against ldap server
|
||||
- shadow => authenticate against local user db
|
||||
- mysql => authenticate against mysql db
|
||||
- rimap => authenticate against imap server
|
||||
- NOTE: can be a list of mechanisms like pam ldap shadow
|
||||
|
||||
##### SASL_MECH_OPTIONS
|
||||
- empty => None
|
||||
- e.g. with sasl_mechanism rimap you need to specify the ip-address/servername of the imap server ==> xxx.xxx.xxx.xxx
|
||||
|
||||
##### SASL_LDAP_SERVER
|
||||
- empty => localhost
|
||||
|
||||
##### SASL_LDAP_PROTO
|
||||
- empty => ldap://
|
||||
- 1 => ldaps://
|
||||
|
||||
##### SASL_LDAP_BIND_DN
|
||||
- empty => anonymous bind
|
||||
- specify an object with priviliges to search the directory tree
|
||||
- e.g. active directory: SASL_BIND_DN=cn=Administrator,cn=Users,dc=mydomain,dc=net
|
||||
- e.g. openldap: SASL_BIND_DN=cn=admin,dc=mydomain,dc=net
|
||||
|
||||
##### SASL_LDAP_PASSWORD
|
||||
- empty => anonymous bind
|
||||
|
||||
##### SASL_LDAP_SEARCH_BASE
|
||||
- empty => Reverting to SASL_MECHANISM pam
|
||||
- specify the search base
|
||||
|
||||
##### SASL_LDAP_FILTER
|
||||
- empty => default filter (uid=%u)
|
||||
- e.g. for active directory: (&(sAMAccountName=%U)(objectClass=person))
|
||||
- e.g. for openldap: (&(uid=%U)(objectClass=person))
|
||||
|
||||
##### LDAP
|
||||
- **empty** => LDAP support disabled
|
||||
- 1 => set virtual_mailbox_maps = ldap:/etc/postfix/ldap-users.cf and virtual_alias_maps = ldap:/etc//postfix/ldap-aliases.cf
|
||||
- $SMTP_ONLY must be set to 1
|
||||
|
||||
##### LDAP_SERVER_HOST
|
||||
- => Specify the dns-name/ip-address where the ldap-server
|
||||
- NOTE: If you going to use the mailserver in combination with docker-compose you can set the service name here
|
||||
|
||||
##### LDAP_SEARCH_BASE
|
||||
- => e.g. LDAP_SEARCH_BASE=dc=mydomain,dc=loc
|
||||
|
||||
##### LDAP_BIND_DN
|
||||
- => take a look at examples of SASL_LDAP_BIND_DN
|
||||
|
||||
##### LDAP_BIND_PW
|
||||
- => Specify the password to bind against ldap
|
||||
|
||||
##### KOPANO
|
||||
- **empty** => LDAP support disabled disabled
|
||||
- 1 => set virtual_transport = ltmp:${KOPANO_DAGENT}:2003
|
||||
|
||||
##### KOPANO_DAGENT
|
||||
- => Specify the dns-name/ip-address where the kopano-dagent can be reached
|
||||
|
||||
##### VIRUSMAILS_DELETE_DELAY
|
||||
|
||||
Set how many days a virusmail will stay on the server before being deleted
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
server_host = localhost
|
||||
search_base = ou=Users,dc=example,dc=com
|
||||
version = 3
|
||||
scope = sub
|
||||
query_filter = (&(objectClass=posixAccount)(kopanoAliases=%s))
|
||||
result_attribute = mail
|
||||
bind_dn =
|
||||
bind_pw =
|
||||
bind = yes
|
|
@ -0,0 +1,10 @@
|
|||
server_host = 192.168.0.100
|
||||
search_base = ou=Users,dc=example,dc=local
|
||||
version = 3
|
||||
bind = yes
|
||||
bind_dn = cn=kopano,ou=Users,dc=example,dc=local
|
||||
bind_pw = secret
|
||||
scope = sub
|
||||
query_filter = (&(objectClass=user)(otherMailbox=%s))
|
||||
result_attribute = mail
|
||||
bind = yes
|
|
@ -0,0 +1,9 @@
|
|||
server_host = localhost
|
||||
search_base = ou=Users,dc=example,dc=com
|
||||
version = 3
|
||||
scope = sub
|
||||
query_filter = (&(objectClass=posixAccount)(kopanoAliases=%s))
|
||||
result_attribute = mail
|
||||
bind_dn =
|
||||
bind_pw =
|
||||
bind = yes
|
|
@ -0,0 +1,9 @@
|
|||
server_host = localhost
|
||||
search_base = ou=Groups,dc=exampple,dc=com
|
||||
version = 3
|
||||
query_filter = (&(objectclass=kopano-group)(mail=%s))
|
||||
leaf_result_attribute = mail
|
||||
special_result_attribute = member
|
||||
bind_dn =
|
||||
bind_pw =
|
||||
bind = yes
|
|
@ -0,0 +1,10 @@
|
|||
server_host = 192.168.0.100
|
||||
search_base = ou=groups,dc=example,dc=local
|
||||
version = 3
|
||||
bind = yes
|
||||
bind_dn = cn=kopano,ou=Users,dc=example,dc=local
|
||||
bind_pw = secret
|
||||
query_filter = (&(objectclass=group)(mail=%s))
|
||||
leaf_result_attribute = mail
|
||||
special_result_attribute = member
|
||||
bind = yes
|
|
@ -0,0 +1,9 @@
|
|||
server_host = localhost
|
||||
search_base = ou=Groups,dc=exampple,dc=com
|
||||
version = 3
|
||||
query_filter = (&(objectclass=kopano-group)(mail=%s))
|
||||
leaf_result_attribute = mail
|
||||
special_result_attribute = member
|
||||
bind_dn =
|
||||
bind_pw =
|
||||
bind = yes
|
|
@ -0,0 +1,9 @@
|
|||
server_host = localhost
|
||||
search_base = ou=Users,dc=example,dc=com
|
||||
version = 3
|
||||
scope = sub
|
||||
query_filter = (&(objectClass=posixAccount)(mail=%s))
|
||||
result_attribute = mail
|
||||
bind_dn =
|
||||
bind_pw =
|
||||
bind = yes
|
|
@ -0,0 +1,10 @@
|
|||
server_host = 192.168.0.100
|
||||
search_base = ou=Users,dc=example,dc=local
|
||||
version = 3
|
||||
bind = yes
|
||||
bind_dn = cn=kopano,ou=Users,dc=example,dc=local
|
||||
bind_pw = secret
|
||||
scope = sub
|
||||
query_filter = (&(objectClass=user)(mail=%s))
|
||||
result_attribute = mail
|
||||
bind = yes
|
|
@ -0,0 +1,9 @@
|
|||
server_host = localhost
|
||||
search_base = ou=Users,dc=example,dc=com
|
||||
version = 3
|
||||
scope = sub
|
||||
query_filter = (&(objectClass=posixAccount)(mail=%s))
|
||||
result_attribute = mail
|
||||
bind_dn =
|
||||
bind_pw =
|
||||
bind = yes
|
|
@ -69,12 +69,14 @@ if [ -f /tmp/docker-mailserver/postfix-accounts.cf ]; then
|
|||
fi
|
||||
# Copy user provided sieve file, if present
|
||||
test -e /tmp/docker-mailserver/${login}.dovecot.sieve && cp /tmp/docker-mailserver/${login}.dovecot.sieve /var/mail/${domain}/${user}/.dovecot.sieve
|
||||
echo ${domain} >> /tmp/vhost.tmp
|
||||
done < /tmp/docker-mailserver/postfix-accounts.cf
|
||||
else
|
||||
echo "==> Warning: 'config/docker-mailserver/postfix-accounts.cf' is not provided. No mail account created."
|
||||
fi
|
||||
|
||||
# Create default vhost file
|
||||
echo ${domain} >> /tmp/vhost.tmp
|
||||
|
||||
#
|
||||
# Aliases
|
||||
#
|
||||
|
@ -258,6 +260,96 @@ case $PERMIT_DOCKER in
|
|||
|
||||
esac
|
||||
|
||||
#
|
||||
# Ldap
|
||||
#
|
||||
for i in 'users' 'groups' 'aliases'; do
|
||||
fpath="/tmp/docker-mailserver/postfix-ldap-${i}.cf"
|
||||
if [ -f $fpath ]; then
|
||||
cp ${fpath} /etc/postfix/ldap-${i}.cf
|
||||
sed -i -e 's|^server_host.*|server_host = '${LDAP_SERVER_HOST}'|g' \
|
||||
-e 's|^search_base.*|search_base = '${LDAP_SEARCH_BASE}'|g' \
|
||||
-e 's|^bind_dn.*|bind_dn = '${LDAP_BIND_DN}'|g' \
|
||||
-e 's|^bind_pw.*|bind_pw = '${LDAP_BIND_PW}'|g' \
|
||||
/etc/postfix/ldap-${i}.cf
|
||||
else
|
||||
echo "${fpath} not found"
|
||||
echo "==> Warning: 'config/postfix-ldap-$i.cf' is not provided."
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $LDAP == 1 ]] && [[ $SMTP_ONLY == 1 ]];then
|
||||
|
||||
echo "Configuring LDAP"
|
||||
[ -f /etc/postfix/ldap-users.cf ] && \
|
||||
postconf -e "virtual_mailbox_maps = ldap:/etc/postfix/ldap-users.cf" || \
|
||||
echo '==> Warning: /etc/postfix/ldap-user.cf not found'
|
||||
|
||||
[ -f /etc/postfix/ldap-aliases.cf ] && \
|
||||
postconf -e "virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf, ldap:/etc/postfix/ldap-groups.cf" || \
|
||||
echo '==> Warning: /etc/postfix/ldap-aliases.cf not found'
|
||||
|
||||
[ ! -f /etc/postfix/sasl/smtpd.conf ] && cat > /etc/postfix/sasl/smtpd.conf << EOF
|
||||
pwcheck_method: saslauthd
|
||||
mech_list: plain login
|
||||
EOF
|
||||
fi
|
||||
|
||||
#
|
||||
# Saslauthd
|
||||
#
|
||||
if [ ${SASLAUTHD} == 1 ];then
|
||||
echo "Configuring Cyrus SASL"
|
||||
# checking env vars and setting defaults
|
||||
[ -z $SASL_MECHANISMS ] && SASL_MECHANISMS=pam
|
||||
[ -z $SASL_LDAP_SEARCH_BASE ] && SASL_MECHANISMS=pam
|
||||
[ -z $SASL_LDAP_SERVER ] && SASL_LDAP_SERVER=localhost
|
||||
[ -z $SASL_LDAP_FILTER ] && SASL_LDAP_FILTER='(uid=%u)'
|
||||
([ $SASL_LDAP_PROTO == 0 ] || [ -z $SASL_LDAP_PROTO ]) && SASL_LDAP_PROTO='ldap://' || SASL_LDAP_PROTO='ldaps://'
|
||||
|
||||
if [ ! -f /etc/saslauthd.conf ];then
|
||||
echo "Creating /etc/saslauthd.conf"
|
||||
cat > /etc/saslauthd.conf << EOF
|
||||
ldap_servers: ${SASL_LDAP_PROTO}${SASL_LDAP_SERVER}
|
||||
|
||||
ldap_auth_method: bind
|
||||
ldap_bind_dn: ${SASL_LDAP_BIND_DN}
|
||||
ldap_password: ${SASL_LDAP_PASSWORD}
|
||||
|
||||
ldap_search_base: ${SASL_LDAP_SEARCH_BASE}
|
||||
ldap_filter: ${SASL_LDAP_FILTER}
|
||||
|
||||
ldap_referrals: yes
|
||||
log_level: 10
|
||||
EOF
|
||||
|
||||
fi
|
||||
|
||||
sed -i -e "/^[^#].*smtpd_sasl_type.*/s/^/#/g" \
|
||||
-e "/^[^#].*smtpd_sasl_path.*/s/^/#/g" \
|
||||
/etc/postfix/master.cf
|
||||
|
||||
sed -i -e "s|^START=.*|START=yes|g" \
|
||||
-e "s|^MECHANISMS=.*|MECHANISMS="\"$SASL_MECHANISMS\""|g" \
|
||||
-e "s|^MECH_OPTIONS=.*|MECH_OPTIONS="\"$SASL_MECH_OPTIONS\""|g" \
|
||||
/etc/default/saslauthd
|
||||
sed -i -e "/smtpd_sasl_path =.*/d" \
|
||||
-e "/smtpd_sasl_type =.*/d" \
|
||||
-e "/dovecot_destination_recipient_limit =.*/d" \
|
||||
/etc/postfix/main.cf
|
||||
gpasswd -a postfix sasl
|
||||
fi
|
||||
|
||||
#
|
||||
# Kopano
|
||||
#
|
||||
if [ $KOPANO == 1 ];then
|
||||
echo 'Configuring Kopano'
|
||||
[ ! -z ${KOPANO_DAGENT} ] && \
|
||||
postconf -e "virtual_transport = lmtp:${KOPANO_DAGENT}:2003" || \
|
||||
echo '$KOPANO_DAGENT not set. Skipping ...'
|
||||
fi
|
||||
|
||||
#
|
||||
# Override Postfix configuration
|
||||
#
|
||||
|
@ -378,57 +470,63 @@ if [ "$ENABLE_MANAGESIEVE" = 1 ]; then
|
|||
echo "Sieve management enabled"
|
||||
mv /etc/dovecot/protocols.d/managesieved.protocol.disab /etc/dovecot/protocols.d/managesieved.protocol
|
||||
fi
|
||||
|
||||
if [ "$SMTP_ONLY" != 1 ]; then
|
||||
# Here we are starting sasl and imap, not pop3 because it's disabled by default
|
||||
echo " * Starting dovecot services"
|
||||
/usr/sbin/dovecot -c /etc/dovecot/dovecot.conf
|
||||
fi
|
||||
# Here we are starting sasl and imap, not pop3 because it's disabled by default
|
||||
echo " * Starting dovecot services"
|
||||
/usr/sbin/dovecot -c /etc/dovecot/dovecot.conf
|
||||
|
||||
if [ "$ENABLE_POP3" = 1 -a "$SMTP_ONLY" != 1 ]; then
|
||||
echo "Starting POP3 services"
|
||||
mv /etc/dovecot/protocols.d/pop3d.protocol.disab /etc/dovecot/protocols.d/pop3d.protocol
|
||||
/usr/sbin/dovecot reload
|
||||
fi
|
||||
if [ "$ENABLE_POP3" = 1 ]; then
|
||||
echo "Starting POP3 services"
|
||||
mv /etc/dovecot/protocols.d/pop3d.protocol.disab /etc/dovecot/protocols.d/pop3d.protocol
|
||||
/usr/sbin/dovecot reload
|
||||
fi
|
||||
|
||||
if [ -f /tmp/docker-mailserver/dovecot.cf ]; then
|
||||
echo 'Adding file "dovecot.cf" to the Dovecot configuration'
|
||||
cp /tmp/docker-mailserver/dovecot.cf /etc/dovecot/local.conf
|
||||
/usr/sbin/dovecot reload
|
||||
if [ -f /tmp/docker-mailserver/dovecot.cf ]; then
|
||||
echo 'Adding file "dovecot.cf" to the Dovecot configuration'
|
||||
cp /tmp/docker-mailserver/dovecot.cf /etc/dovecot/local.conf
|
||||
/usr/sbin/dovecot reload
|
||||
fi
|
||||
fi
|
||||
|
||||
# Enable fetchmail daemon
|
||||
if [ "$ENABLE_FETCHMAIL" = 1 ]; then
|
||||
/usr/local/bin/setup-fetchmail
|
||||
echo "Fetchmail enabled"
|
||||
/etc/init.d/fetchmail start
|
||||
/usr/local/bin/setup-fetchmail
|
||||
echo "Fetchmail enabled"
|
||||
/etc/init.d/fetchmail start
|
||||
fi
|
||||
|
||||
# Start services related to SMTP
|
||||
if ! [ "$DISABLE_CLAMAV" = 1 ]; then
|
||||
/etc/init.d/clamav-daemon start
|
||||
/etc/init.d/clamav-daemon start
|
||||
fi
|
||||
|
||||
# Copy user provided configuration files if provided
|
||||
if [ -f /tmp/docker-mailserver/amavis.cf ]; then
|
||||
cp /tmp/docker-mailserver/amavis.cf /etc/amavis/conf.d/50-user
|
||||
cp /tmp/docker-mailserver/amavis.cf /etc/amavis/conf.d/50-user
|
||||
fi
|
||||
|
||||
if ! [ "$DISABLE_AMAVIS" = 1 ]; then
|
||||
/etc/init.d/amavis start
|
||||
/etc/init.d/amavis start
|
||||
fi
|
||||
|
||||
if [[ $SMTP_ONLY == 1 ]] && [[ $LDAP == 1 ]]; then
|
||||
/etc/init.d/saslauthd start
|
||||
fi
|
||||
|
||||
/etc/init.d/opendkim start
|
||||
/etc/init.d/opendmarc start
|
||||
/etc/init.d/postfix start
|
||||
|
||||
if [ "$ENABLE_FAIL2BAN" = 1 ]; then
|
||||
echo "Starting fail2ban service"
|
||||
touch /var/log/auth.log
|
||||
/etc/init.d/fail2ban start
|
||||
echo "Starting fail2ban service"
|
||||
touch /var/log/auth.log
|
||||
/etc/init.d/fail2ban start
|
||||
fi
|
||||
|
||||
echo "Listing users"
|
||||
/usr/sbin/dovecot user '*'
|
||||
if [ ! "$SMTP_ONLY" == 1 ];then
|
||||
echo "Listing users"
|
||||
/usr/sbin/dovecot user '*'
|
||||
fi
|
||||
|
||||
echo "Starting..."
|
||||
tail -f /var/log/mail/mail.log
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
server_host = 192.168.0.100
|
||||
search_base = ou=Users,dc=example,dc=local
|
||||
version = 3
|
||||
bind = yes
|
||||
bind_dn = cn=kopano,ou=Users,dc=example,dc=local
|
||||
bind_pw = secret
|
||||
scope = sub
|
||||
query_filter = (&(objectClass=user)(otherMailbox=%s))
|
||||
result_attribute = mail
|
||||
bind = yes
|
|
@ -0,0 +1,10 @@
|
|||
server_host = 192.168.0.100
|
||||
search_base = ou=groups,dc=example,dc=local
|
||||
version = 3
|
||||
bind = yes
|
||||
bind_dn = cn=kopano,ou=Users,dc=example,dc=local
|
||||
bind_pw = secret
|
||||
query_filter = (&(objectclass=group)(mail=%s))
|
||||
leaf_result_attribute = mail
|
||||
special_result_attribute = member
|
||||
bind = yes
|
|
@ -0,0 +1,10 @@
|
|||
server_host = 192.168.0.100
|
||||
search_base = ou=Users,dc=example,dc=local
|
||||
version = 3
|
||||
bind = yes
|
||||
bind_dn = cn=kopano,ou=Users,dc=example,dc=local
|
||||
bind_pw = secret
|
||||
scope = sub
|
||||
query_filter = (&(objectClass=user)(mail=%s))
|
||||
result_attribute = mail
|
||||
bind = yes
|
Loading…
Reference in New Issue