diff --git a/Makefile b/Makefile deleted file mode 100644 index 4ea4cca..0000000 --- a/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -all: build - -.PHONY: build - -build: - docker build -t dockermail_made_special:2.11.1 . - -run: - 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_made_special:2.11.1 diff --git a/README.md b/README.md index 9e6eaed..745fda8 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,29 @@ -docker-made-special-mail +Dockermail ========== -Based on https://github.com/lava/dockermail - -A secure, minimal-configuration mail server in a docker container. +A secure, minimal-configuration mail server in a docker containers. This repository is tailored to small private servers, where you own a domain and want to host your own mail. -This container uses postfix as MTA and dovecot as IMAP server. -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. +The setup is modular and so far has (more to come, feel free to contribute :) -SPAM stuff -===== -Outgoing mail is signed by OpenDKIM, you need to generate a key and set up your domain records (see step 5). -You should add PTR record to your IP (aka reverse DNS) which is done by your server provider. +* `email_core` - base SMTP and IMAP server +* `opendkim` - adds DKIM signing service to the core + +Please see the README in each folder for more information on each image. + +### SPAM +Although OpenDKIM is optional, I highly recommended you use it unless you want your mail to end up in someone's spam folder. See the README in `opendkim` folder for more info on setting it up. + +You should also add PTR record to your IP (aka Reverse DNS) which is done by your server provider. And finally, generate and add an SPF record to your domain, search for instructions on this - there are a few generator site around and the setup steps depend on your domain name provider. +### Compose +Assuming you follow the instructions in the accompanying READMEs to set up both containers, you should just be able to run -Setup -===== -Create 2 folders: one for mail configuration (`/opt/dockermail/settings`), another for mail storage (`/opt/dockermail/vmail`). -Use the the example config files in `config/example` of this repo. + docker-compose up -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`, like - - 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 dockermail bash` to attach to the running container (step 7) and run `doveadm pw -s ` inside. - -4. Change the hostname in file `/opt/dockermail/settings/myhostname` to the correct fully qualified domain of your server. - -5. Add DKIM settings files: `/opt/dockermail/settings/opendkim.conf` and `/opt/dockermail/settings/mail.private` - See https://help.ubuntu.com/community/Postfix/DKIM on the info about these settings. - You will need to generate your own `mail.private` key and set up your domain records, the `opendkim.conf` from `config/example` - is ready to use. - -6. Build container - - make - -7. Run container and map ports 25 and 143 from the host to the container. - To store your mail outside the container, map `/opt/dockermail/vmail/` to - a directory on your host. (This is recommended, otherwise - you have to remember to backup your mail when you want to restart 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_made_special/2.11.1` - -8. Enjoy! +and it will spin up both container and link them together, easy! -TODO -===== -1. Split out DKIM into a seperate container, which can be linked in to postfix. -2. Add ability to plug other components from linked containers (SPAM filters, Autoresponders etc) -3. Provider an easy way to compose these into a working mail system. +### Coming soon +* Incoming SPAM filter! diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9641f63 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +emailcore: + build: ./email_core + ports: + - "25:25" + - "143:143" + - "587:587" + volumes: + - /opt/dockermail/settings:/mail_settings + - /opt/dockermail/vmail:/vmail + links: + - opendkim +opendkim: + build: ./opendkim + volumes: + - /opt/dockermail/settings:/mail_settings diff --git a/email_core/Dockerfile b/email_core/Dockerfile index abe5d4f..c306ac1 100644 --- a/email_core/Dockerfile +++ b/email_core/Dockerfile @@ -7,35 +7,37 @@ RUN locale-gen en_GB en_GB.UTF-8 && dpkg-reconfigure locales RUN apt-get update && apt-get install -y \ ssl-cert \ postfix \ - dovecot-imapd \ + dovecot-imapd && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -# postfix configuration +# 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 -# configure settings script -VOLUME ["/mail_settings"] -COPY boot /boot -RUN chmod 755 /boot - -# add user vmail who own all mail folders -VOLUME ["/vmail"] -RUN groupadd -g 5000 vmail -RUN useradd -g vmail -u 5000 vmail -d /vmail -m - -# dovecot configuration +# Dovecot configuration ADD ./config/dovecot.mail /etc/dovecot/conf.d/10-mail.conf ADD ./config/dovecot.ssl /etc/dovecot/conf.d/10-ssl.conf ADD ./config/dovecot.auth /etc/dovecot/conf.d/10-auth.conf ADD ./config/dovecot.master /etc/dovecot/conf.d/10-master.conf ADD ./config/dovecot.lda /etc/dovecot/conf.d/15-lda.conf ADD ./config/dovecot.imap /etc/dovecot/conf.d/20-imap.conf - # Uncomment to add verbose logging # ADD ./config/dovecot.logging /etc/dovecot/conf.d/10-logging.conf +# Nice place for your settings +VOLUME ["/mail_settings"] + +# Configure boot script +COPY boot / +RUN chmod 755 /boot + +# 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 rsyslog start; service postfix start; dovecot -F diff --git a/email_core/README.md b/email_core/README.md new file mode 100644 index 0000000..d2e5232 --- /dev/null +++ b/email_core/README.md @@ -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 ` 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` diff --git a/email_core/boot b/email_core/boot index 20fd09a..e43c592 100644 --- a/email_core/boot +++ b/email_core/boot @@ -1,10 +1,12 @@ # 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 @@ -12,32 +14,52 @@ 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 +# Configure mail delivery to dovecot cp /mail_settings/aliases /etc/postfix/virtual cp /mail_settings/domains /etc/postfix/virtual-mailbox-domains -# parse mailbox settings +# 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 +# Give postfix ownership of its files chown -R postfix:postfix /etc/postfix -# map virtual aliases and user/filesystem mappings +# 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 +# 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 + + +# OpenDKIM config +POSTFIX_MAIN_CF=/etc/postfix/main.cf +if [ -z "$OPEN_DKIM" ]; then + # Add config block if not present already + if grep -q "# OpenDKIM - dockermail" "$POSTFIX_MAIN_CF"; then + echo "# OpenDKIM - dockermail" >> "$POSTFIX_MAIN_CF" + echo "milter_default_action = accept" >> "$POSTFIX_MAIN_CF" + echo "milter_protocol = 2" >> "$POSTFIX_MAIN_CF" + echo "smtpd_milters = $OPEN_DKIM_PORT_8891_ADDR" >> "$POSTFIX_MAIN_CF" + echo "non_smtpd_milters = $OPEN_DKIM_PORT_8891_ADDR" >> "$POSTFIX_MAIN_CF" + echo "# OpenDKIM - dockermail - end" >> "$POSTFIX_MAIN_CF" + fi +else + # Remove OpenDKIM block + sed '/# OpenDKIM - dockermail/,/# OpenDKIM - dockermail - end/d' "$POSTFIX_MAIN_CF" +fi diff --git a/email_core/config/postfix.main.cf b/email_core/config/postfix.main.cf index 36f7f42..a3420ed 100644 --- a/email_core/config/postfix.main.cf +++ b/email_core/config/postfix.main.cf @@ -69,9 +69,3 @@ smtpd_tls_auth_only = yes smtpd_sasl_auth_enable = yes smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth - -# DKIM -milter_default_action = accept -milter_protocol = 2 -smtpd_milters = inet:localhost:8891 -non_smtpd_milters = inet:localhost:8891 diff --git a/opendkim/Dockerfile b/opendkim/Dockerfile index 4824c0c..d67261a 100644 --- a/opendkim/Dockerfile +++ b/opendkim/Dockerfile @@ -9,10 +9,15 @@ RUN apt-get update && apt-get install -y \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -# configure settings script +# Nice place for your settings VOLUME ["/mail_settings"] -COPY boot /boot + +# Configure boot script +COPY boot / RUN chmod 755 /boot -# start necessary services for operation (dovecot -F starts dovecot in the foreground to prevent container exit) -ENTRYPOINT /boot; service rsyslog start; opendkim -f +ENV OPEN_DKIM true +ENV OPEN_DKIM_PORT_8891_ADDR inet:8891 + +EXPOSE 8891 +ENTRYPOINT ./boot; service rsyslog start; opendkim -f -p $OPEN_DKIM_PORT_8891_ADDR diff --git a/opendkim/README.md b/opendkim/README.md new file mode 100644 index 0000000..4e2fba7 --- /dev/null +++ b/opendkim/README.md @@ -0,0 +1,18 @@ +Dockermail - OpenDKIM +=== +Once configured and linked to the `email_core`, this image will provide DKIM singing for your mail. +Please see http://www.opendkim.org/ for more information on OpenDKIM. + +### Configuration +To get going you need to generate a key and set up your domain records (see step 5). + +This images uses settings files in an attached volume to configure the container on boot. +You can place these in the same folder as the `email_core`'s settings for easy administration. + + * `opendkim.conf` + You will find this file in the './config', change `Domain` to your own domain. + + * `mail.private` + You will need to generate this private key file and use the public key in your domain's DNS setup. + +See https://help.ubuntu.com/community/Postfix/DKIM for info on generating keys and setting up your domain. diff --git a/opendkim/boot b/opendkim/boot old mode 100644 new mode 100755 index 8011a8c..9e88114 --- a/opendkim/boot +++ b/opendkim/boot @@ -1,5 +1,5 @@ # Copy OpenDKIM config cp /mail_settings/opendkim.conf /etc/opendkim.conf cp /mail_settings/mail.private /etc/dkim.key -chown opendkim:opendkim /etc/dkim.key +chown root:root /etc/dkim.key chmod 600 /etc/dkim.key diff --git a/opendkim/config/example/opendkim.conf b/opendkim/config/opendkim.conf similarity index 96% rename from opendkim/config/example/opendkim.conf rename to opendkim/config/opendkim.conf index 88bf015..c72e79b 100644 --- a/opendkim/config/example/opendkim.conf +++ b/opendkim/config/opendkim.conf @@ -14,7 +14,7 @@ Syslog yes # Sign for example.com with key in /etc/mail/dkim.key using # selector '2007' (e.g. 2007._domainkey.example.com) Domain example.com -KeyFile /etc/dkim.key # See bellow how to generate and set up the key +KeyFile /etc/dkim.key Selector mail # Common settings. See dkim-filter.conf(5) for more information.