Move email_core to core

This commit is contained in:
Val
2015-07-27 12:23:08 +01:00
parent 8b2ef783ef
commit 4a21fde147
21 changed files with 3 additions and 3 deletions

48
core/Dockerfile Normal file
View File

@@ -0,0 +1,48 @@
FROM ubuntu:14.10
ENV DEBIAN_FRONTEND noninteractive
RUN locale-gen en_GB en_GB.UTF-8 && dpkg-reconfigure locales
# Prerequisites
RUN echo "#!/bin/sh\nexit 0" > /usr/sbin/policy-rc.d && \
apt-get update && apt-get install -y \
ssl-cert \
postfix \
dovecot-imapd && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Postfix configuration
ADD ./config/postfix.main.cf /etc/postfix/main.cf
ADD ./config/postfix.master.cf.append /etc/postfix/master-additional.cf
RUN cat /etc/postfix/master-additional.cf >> /etc/postfix/master.cf
# Dovecot configuration
COPY ./config/dovecot.mail /etc/dovecot/conf.d/10-mail.conf
COPY ./config/dovecot.ssl /etc/dovecot/conf.d/10-ssl.conf
COPY ./config/dovecot.auth /etc/dovecot/conf.d/10-auth.conf
COPY ./config/dovecot.master /etc/dovecot/conf.d/10-master.conf
COPY ./config/dovecot.lda /etc/dovecot/conf.d/15-lda.conf
COPY ./config/dovecot.imap /etc/dovecot/conf.d/20-imap.conf
# Uncomment to add verbose logging
# COPY ./config/dovecot.logging /etc/dovecot/conf.d/10-logging.conf
COPY ./config/rsyslog.conf /etc/rsyslog.conf
# Nice place for your settings
VOLUME ["/mail_settings"]
# Copy boot scripts
COPY boot /
RUN chmod 755 /boot
COPY boot.d /boot.d
RUN chmod -R 755 /boot.d
# Volume to store email
VOLUME ["/vmail"]
# Add user vmail that ownes mail
RUN groupadd -g 5000 vmail
RUN useradd -g vmail -u 5000 vmail -d /vmail -m
EXPOSE 25 143 587
ENTRYPOINT /boot; service postfix start; service dovecot start; rsyslogd -n

46
core/README.md Normal file
View File

@@ -0,0 +1,46 @@
Dockermail - Email Core
==========
This image provides a secure, minimal mail server based on 'postfix' and 'dovecot'.
All incoming mail to your domains is accepted.
For outgoing mail, only authenticated (logged in with username and password) clients can send messages via STARTTLS.
### Setup
You will need 2 folder on your host, one to store your configuration and another one to store your email.
In the instructions below we will use the following:
* `/opt/dockermail/settings` to store configuration
* `/opt/dockermail/vmail` to store the mail
Use the the example config files in `config/example` to get you started.
1. Add all domains you want to receive mail for to the file `/opt/dockermail/settings/domains`, like this:
example.org
example.net
2. Add user aliases to the file `/opt/dockermail/settings/aliases`:
johndoe@example.org john.doe@example.org
john.doe@example.org john.doe@example.org
admin@forum.example.org forum-admin@example.org
@example.net catch-all@example.net
An IMAP mail account is created for each entry on the right hand side.
Every mail sent to one of the addresses in the left column will be delivered to the corresponding account in the right column.
3. Add user passwords to the file `/opt/dockermail/settings/passwords` like this
john.doe@example.org:{PLAIN}password123
admin@example.org:{SHA256-CRYPT}$5$ojXGqoxOAygN91er$VQD/8dDyCYOaLl2yLJlRFXgl.NSrB3seZGXBRMdZAr6
To get the hash values, you can either install dovecot locally or use `docker exec -it [email_core_container_name] bash` to attach to the running container (step 6) and run `doveadm pw -s <scheme-name>` inside, remember to restart your container if you update the settings!
4. Change the hostname in file `/opt/dockermail/settings/myhostname` to the correct fully qualified domain of your server.
5. Build container
docker build -t dockermail_email_core .
6. Run container and map ports 25 and 143 from the host to the container.
`docker run -name dockermail -d -p 25:25 -p 587:587 -p 143:143 -v /opt/dockermail/settings:/mail_settings -v /opt/dockermail/vmail:/vmail dockermail_email_core`

57
core/boot Executable file
View File

@@ -0,0 +1,57 @@
#!/bin/bash
# Check if we have SSL certificates in config, otherwise copy it there
# First the key file
if [ -f /mail_settings/ssl-cert-snakeoil.key ]; then
cp /mail_settings/ssl-cert-snakeoil.key /etc/ssl/private/ssl-cert-snakeoil.key
else
cp /etc/ssl/private/ssl-cert-snakeoil.key /mail_settings/ssl-cert-snakeoil.key
fi
# Then the pem file
if [ -f /mail_settings/ssl-cert-snakeoil.pem ]; then
cp /mail_settings/ssl-cert-snakeoil.pem /etc/ssl/certs/ssl-cert-snakeoil.pem
else
cp /etc/ssl/certs/ssl-cert-snakeoil.pem /mail_settings/ssl-cert-snakeoil.pem
fi
# Update hostname if given
if [ -f /mail_settings/myhostname ]; then
sed -i -e "s/myhostname = localhost/myhostname = $(sed 's:/:\\/:g' /mail_settings/myhostname)/" /etc/postfix/main.cf
echo $(sed 's:/:\\/:g' /mail_settings/myhostname) > /etc/mailname
fi
# Configure mail delivery to dovecot
cp /mail_settings/aliases /etc/postfix/virtual
cp /mail_settings/domains /etc/postfix/virtual-mailbox-domains
# Parse mailbox settings
mkdir /etc/postfix/tmp
awk < /etc/postfix/virtual '{ print $2 }' > /etc/postfix/tmp/virtual-receivers
sed -r 's,(.+)@(.+),\2/\1/,' /etc/postfix/tmp/virtual-receivers > /etc/postfix/tmp/virtual-receiver-folders
paste /etc/postfix/tmp/virtual-receivers /etc/postfix/tmp/virtual-receiver-folders > /etc/postfix/virtual-mailbox-maps
# Give postfix ownership of its files
chown -R postfix:postfix /etc/postfix
# Map virtual aliases and user/filesystem mappings
postmap /etc/postfix/virtual
postmap /etc/postfix/virtual-mailbox-maps
chown -R postfix:postfix /etc/postfix
# Make user vmail own all mail folders
chown -R vmail:vmail /vmail
chmod u+w /vmail
# Add password file
cp /mail_settings/passwords /etc/dovecot/passwd
# Run boot scripts
for SCRIPT in /boot.d/*
do
if [ -f "$SCRIPT" -a -x "$SCRIPT" ]; then
"$SCRIPT"
fi
done

76
core/boot.d/amavis Normal file
View File

@@ -0,0 +1,76 @@
#!/bin/bash
echo 'Running amavis boot script'
POSTFIX_MAIN_CF=/etc/postfix/main.cf
POSTFIX_MASTER_CF=/etc/postfix/master.cf
env_dump=$(printenv)
AMAVIS_CONFIG_HEADER="# Amavis - dockermail - start"
AMAVIS_CONFIG_FOOTER="# Amavis - dockermail - end"
function remove_amavis () {
# main.cf
if grep -q "$AMAVIS_CONFIG_HEADER" "$POSTFIX_MAIN_CF"; then
sed "/$AMAVIS_CONFIG_HEADER/,/$AMAVIS_CONFIG_FOOTER/d" "$POSTFIX_MAIN_CF" -i
fi
# master.cf
sed '/^pickup/,/^cleanup/{//!d}' "$POSTFIX_MASTER_CF" -i
sed "/$AMAVIS_CONFIG_HEADER/,/$AMAVIS_CONFIG_FOOTER/d" "$POSTFIX_MASTER_CF" -i
}
function add_amavis () {
# main.cf
if ! grep -q "$AMAVIS_CONFIG_HEADER" "$POSTFIX_MAIN_CF"; then
echo "$AMAVIS_CONFIG_HEADER" >> "$POSTFIX_MAIN_CF"
echo "content_filter = smtp-amavis:[amavis]:10024" >> "$POSTFIX_MAIN_CF"
echo "$AMAVIS_CONFIG_FOOTER" >> "$POSTFIX_MAIN_CF"
else
echo "Warning: $POSTFIX_MAIN_CF already contains Amavis configuration, skipping"
fi
# master.cf
if ! grep -q "$AMAVIS_CONFIG_HEADER" "$POSTFIX_MASTER_CF"; then
sed "/^pickup.*/a \ -o content_filter= \n -o receive_override_options=no_header_body_checks" $POSTFIX_MASTER_CF -i
echo "$AMAVIS_CONFIG_HEADER" >> $POSTFIX_MASTER_CF
echo "smtp-amavis unix - - - - 2 smtp" >> $POSTFIX_MASTER_CF
echo " -o smtp_data_done_timeout=1200" >> $POSTFIX_MASTER_CF
echo " -o smtp_send_xforward_command=yes" >> $POSTFIX_MASTER_CF
echo " -o disable_dns_lookups=yes" >> $POSTFIX_MASTER_CF
echo " -o max_use=20" >> $POSTFIX_MASTER_CF
echo "0.0.0.0:10025 inet n - - - - smtpd" >> $POSTFIX_MASTER_CF
echo " -o content_filter=" >> $POSTFIX_MASTER_CF
echo " -o local_recipient_maps=" >> $POSTFIX_MASTER_CF
echo " -o relay_recipient_maps=" >> $POSTFIX_MASTER_CF
echo " -o smtpd_restriction_classes=" >> $POSTFIX_MASTER_CF
echo " -o smtpd_delay_reject=no" >> $POSTFIX_MASTER_CF
echo " -o smtpd_client_restrictions=permit_mynetworks,reject" >> $POSTFIX_MASTER_CF
echo " -o smtpd_helo_restrictions=" >> $POSTFIX_MASTER_CF
echo " -o smtpd_sender_restrictions=" >> $POSTFIX_MASTER_CF
echo " -o smtpd_recipient_restrictions=permit_mynetworks,reject" >> $POSTFIX_MASTER_CF
echo " -o smtpd_data_restrictions=reject_unauth_pipelining" >> $POSTFIX_MASTER_CF
echo " -o smtpd_end_of_data_restrictions=" >> $POSTFIX_MASTER_CF
# Allow the private ip range 172.x.x.x that Docker apparently uses
echo " -o mynetworks=172.0.0.0/8" >> $POSTFIX_MASTER_CF
echo " -o smtpd_error_sleep_time=0" >> $POSTFIX_MASTER_CF
echo " -o smtpd_soft_error_limit=1001" >> $POSTFIX_MASTER_CF
echo " -o smtpd_hard_error_limit=1000" >> $POSTFIX_MASTER_CF
echo " -o smtpd_client_connection_count_limit=0" >> $POSTFIX_MASTER_CF
echo " -o smtpd_client_connection_rate_limit=0" >> $POSTFIX_MASTER_CF
echo " -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks" >> $POSTFIX_MASTER_CF
echo "$AMAVIS_CONFIG_FOOTER" >> $POSTFIX_MASTER_CF
else
echo "Warning: $POSTFIX_MASTER_CF already contains Amavis configuration, skipping"
fi
}
if [[ $env_dump =~ ^(.+AMAVIS)= ]] ; then
if [ ! -z "${BASH_REMATCH[1]}" ]; then
echo "AMAVIS env set, enabling SPAM filter"
add_amavis
fi
else
echo "Cant find AMAVIS env, SPAM filter will be disabled"
remove_amavis
fi
echo 'Finished amavis boot script'

40
core/boot.d/opendkim Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
echo 'Running opendkim boot script'
POSTFIX_MAIN_CF=/etc/postfix/main.cf
env_dump=$(printenv)
OPENDKIM_CONFIG_HEADER="# OpenDKIM - dockermail - start"
OPENDKIM_CONFIG_FOOTER="# OpenDKIM - dockermail - end"
function remove_opendkim () {
if grep -q "$OPENDKIM_CONFIG_HEADER" "$POSTFIX_MAIN_CF"; then
sed "/$OPENDKIM_CONFIG_HEADER/,/$OPENDKIM_CONFIG_FOOTER/d" "$POSTFIX_MAIN_CF" -i
fi
}
function add_opendkim () {
if ! grep -q "$OPENDKIM_CONFIG_HEADER" "$POSTFIX_MAIN_CF"; then
echo "$OPENDKIM_CONFIG_HEADER" >> "$POSTFIX_MAIN_CF"
echo "milter_default_action = accept" >> "$POSTFIX_MAIN_CF"
echo "milter_protocol = 2" >> "$POSTFIX_MAIN_CF"
echo "smtpd_milters = inet:opendkim:8891" >> "$POSTFIX_MAIN_CF"
echo "non_smtpd_milters = inet:opendkim:8891" >> "$POSTFIX_MAIN_CF"
echo "$OPENDKIM_CONFIG_FOOTER" >> "$POSTFIX_MAIN_CF"
else
echo "Warning: $POSTFIX_MAIN_CF already contains OpenDKIM configuration, skipping"
fi
}
if [[ $env_dump =~ ^(.+OPEN_DKIM)= ]] ; then
if [ ! -z "${BASH_REMATCH[1]}" ]; then
echo "OPEN_DKIM env set, enabling email signing"
add_opendkim
fi
else
echo "Cant find OPEN_DKIM env, signing will be disabled"
remove_opendkim
fi
echo 'Finished opendkim boot script'

11
core/config/dovecot.auth Normal file
View File

@@ -0,0 +1,11 @@
auth_mechanisms = plain login
passdb {
driver = passwd-file
args = /etc/dovecot/passwd
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/vmail/%d/%n allow_all_users=yes
}

3
core/config/dovecot.imap Normal file
View File

@@ -0,0 +1,3 @@
protocol imap {
imap_client_workarounds = tb-extra-mailbox-sep
}

5
core/config/dovecot.lda Normal file
View File

@@ -0,0 +1,5 @@
protocol lda {
hostname = mail.docker.container
postmaster_address = postmaster@mail.docker.container
mail_plugin_dir = /usr/lib/dovecot/modules/lda
}

View File

@@ -0,0 +1,2 @@
auth_verbose = yes
auth_debug = yes

19
core/config/dovecot.mail Normal file
View File

@@ -0,0 +1,19 @@
mail_location = maildir:/vmail/%d/%n:LAYOUT=fs
namespace inbox {
inbox = yes
# set these to autocreate or else thunderbird will complain
mailbox Trash {
auto = create
special_use = \Trash
}
mailbox Drafts {
auto = subscribe
special_use = \Drafts
}
mailbox Sent {
auto = subscribe # autocreate and autosubscribe the Sent mailbox
special_use = \Sent
}
}

View File

@@ -0,0 +1,33 @@
service imap-login {
inet_listener imap {
}
#disable imaps since we use TLS connections through the standard imap
inet_listener imaps {
port = 0
}
}
service imap {
}
# not sure if this is needed
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
group = vmail
mode = 0660
user = postfix
}
}
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = vmail
}
}
service auth-worker {
}

5
core/config/dovecot.ssl Normal file
View File

@@ -0,0 +1,5 @@
ssl = required
disable_plaintext_auth = yes
ssl_cert = </etc/dovecot/dovecot.pem
ssl_key = </etc/dovecot/private/dovecot.pem

View File

@@ -0,0 +1,2 @@
admin@example.org admin@example.org
@example.org catch-all@example.org

View File

@@ -0,0 +1 @@
example.org

View File

@@ -0,0 +1 @@
localhost

View File

@@ -0,0 +1,2 @@
catch-all@example.org:{PLAIN}password123
admin@example.org:{SHA256-CRYPT}$5$3qaCC/fV65Adtfoy$O20EXoSOcgWKf5NyAZnXAtGPQoSgeYRjLm56M25.H12

View File

@@ -0,0 +1,71 @@
# See /usr/share/postfix/main.cf.dist for a commented, more complete version
# Debian specific: Specifying a file name will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname
smtpd_banner = $myhostname ESMTP $mail_name
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
readme_directory = no
# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.
myhostname = localhost
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = /etc/mailname, localhost.localdomain, localhost
relayhost =
mynetworks = 127.0.0.0/8 172.0.0.0/8
mailbox_size_limit = 0
recipient_delimiter = +
# SMTP configuration for incoming mail (port 25)
# Outgoing mail (port 587) configuration is specified in master.cf
# allow all connections (since we want to receive mail from outside)
smtpd_client_restrictions = permit
# Don't talk to mail systems that don't know their own hostname.
# With Postfix < 2.3, specify reject_unknown_hostname.
smtpd_helo_restrictions = permit
# Don't accept mail from domains that don't exist.
smtpd_sender_restrictions = permit
# Only accept mail where this server is the final destination
smtpd_relay_restrictions = permit_auth_destination, permit_mynetworks, reject
# Mail thats not for us gets filtered out by smtpd_relay_restrictions
# When the mail is for us, we just accept everything. (could add spam blocklists/user checking etc. here)
smtpd_recipient_restrictions = permit
# Delivery to dovecot
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
virtual_alias_maps = hash:/etc/postfix/virtual
virtual_mailbox_domains = /etc/postfix/virtual-mailbox-domains
virtual_mailbox_maps = hash:/etc/postfix/virtual-mailbox-maps
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
# additional authentication settings
smtpd_tls_auth_only = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth

View File

@@ -0,0 +1,15 @@
dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}
# we need to be permissive with the helo restrictions since the client can only
# authenticate after HELO has been sent
submission inet n - n - - smtpd
-o smtpd_etrn_restrictions=reject
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth
-o smtpd_sasl_auth_enable=yes
-o smtpd_helo_restrictions=permit
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_sender_restrictions=permit_sasl_authenticated,reject
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject

28
core/config/rsyslog.conf Normal file
View File

@@ -0,0 +1,28 @@
# /etc/rsyslog.conf Configuration file for rsyslog.
#
# For more information see
# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html
#
# Default logging rules can be found in /etc/rsyslog.d/50-default.conf
#################
#### MODULES ####
#################
$ModLoad imuxsock # provides support for local system logging
###########################
#### GLOBAL DIRECTIVES ####
###########################
# Filter duplicated messages
$RepeatedMsgReduction on
#
# Where to place spool and state files
#
$WorkDirectory /var/spool/rsyslog
# Write everything to stdout
$template fmt,"%timestamp:::date-rfc3164%\n"
*.* /dev/stdout