From 47a5166383a4ecae780ffd6ad2081dc3f070bd45 Mon Sep 17 00:00:00 2001 From: andryyy Date: Sun, 11 Dec 2016 18:58:29 +0100 Subject: [PATCH] Add pdns resolver, changed some other files --- README.md | 93 ++++++++++++++++++++++++-------- build-all.sh | 3 +- build-dovecot.sh | 6 +-- build-pdns.sh | 36 +++++++++++++ build-postfix.sh | 8 +++ build-rspamd.sh | 8 +++ data/Dockerfiles/pdns/Dockerfile | 18 +++++++ data/conf/nginx/site.conf | 5 ++ data/conf/pdns/pdns_custom.lua | 1 + data/conf/pdns/recursor.conf | 41 ++++++++++++++ data/conf/postfix/main.cf | 9 ++-- mailcow.conf | 15 +----- 12 files changed, 201 insertions(+), 42 deletions(-) create mode 100755 build-pdns.sh create mode 100644 data/Dockerfiles/pdns/Dockerfile create mode 100644 data/conf/pdns/pdns_custom.lua create mode 100644 data/conf/pdns/recursor.conf diff --git a/README.md b/README.md index 003a6e14..8e2119f7 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,81 @@ # mailcow-dockerized +mailcow dockerized comes with 11 containers linked in a mailcow network: +Dovecot, Memcached, Redis, MariaDB, PowerDNS Recursor, PHP-FPM, Postfix, Nginx, Rmilter, Rspamd and SOGo. + ## Installation 1. Open mailcow.conf and change stuff, do not use special chars in passwords. This will be fixed soon. 2. Run ./build-all.sh -3. Set a rspamd controller password (see section "rspamd") - Done. -The default username for mailcow is `admin` with password `moohoo`. +You can now access https://${MAILCOW_HOSTNAME} with the default credentials `admin` + password `moohoo`. -## Usage +## Configuration after installation + +### Rspamd UI access +If you want to use Rspamds web UI, you need to set a Rspamd controller password: + +``` +# Generate hash +docker exec -it rspamd-mailcow rspamadm pw +``` + +Replace given hash in data/conf/rspamd/override.d/worker-controller.inc: +``` +enable_password = "myhash"; +``` + +Restart rspamd: +``` +docker restart rspamd-mailcow +``` + +Open https://${MAILCOW_HOSTNAME}/rspamd in a browser. + +### SSL (or: How to use Let's Encrypt) +mailcow dockerized comes with a self-signed certificate. + +First you should renew the DH parameters. Assuming you are in the mailcow root folder: +``` +openssl dhparam -out ./data/assets/ssl/dhparams.pem 2048 +``` + +Get the certbot client: +``` +wget https://dl.eff.org/certbot-auto && chmod +x certbot-auto +``` + +Please disable applications blocking port 80 and run certbot: +``` +./certbot-auto certonly \ + --standalone \ + --standalone-supported-challenges http-01 \ + -d ${MAILCOW_HOSTNAME} \ + --email you@example.org \ + --agree-tos +``` + +Link certificates to assets directory. Assuming you are still in the mailcow root folder: +``` +mv data/assets/ssl/mail.{crt,crt_old} +mv data/assets/ssl/mail.{key,key_old} +ln -s /etc/letsencrypt/live/${MAILCOW_HOSTNAME}/fullchain.pem data/assets/ssl/mail.crt +ln -s /etc/letsencrypt/live/${MAILCOW_HOSTNAME}/privkey.pem data/assets/ssl/mail.key +``` + +Restart containers which use the certificate: +``` +docker restart postfix-mailcow +docker restart dovecot-mailcow +docker restart nginx-mailcow +``` + +When renewing certificates, run the last two steps as post-hook in certbot. + +## Special usage ### build-*.files (Re)build a container: @@ -52,6 +115,10 @@ Dump database to file backup_${DBNAME}_${DATE}.sql: ./build-sql.sh --dump ``` +Restore database from a file: +``` +./build-sql.sh --restore filename + ### Redis Connect to redis database: @@ -59,7 +126,7 @@ Connect to redis database: ./build-sql.sh --client ``` -### rspamd +### Rspamd examples Use rspamadm: ``` @@ -71,22 +138,6 @@ Use rspamc: docker exec -it rspamd-mailcow rspamc --help ``` -Set rspamd controller password: -``` -# Generate hash -docker exec -it rspamd-mailcow rspamadm pw -``` - -Replace given hash in data/conf/rspamd/override.d/worker-controller.inc: -``` -enable_password = "myhash"; -``` - -Restart rspamd: -``` -docker restart rspamd-mailcow -``` - ### Remove persistent data MariaDB: diff --git a/build-all.sh b/build-all.sh index 75ebc8b3..ee8ae793 100755 --- a/build-all.sh +++ b/build-all.sh @@ -1,8 +1,9 @@ #!/bin/bash /bin/bash build-network.sh +/bin/bash build-pdns.sh [[ $? != 0 ]] && exit 1 -for buildx in $(ls build-*.sh | grep -vE "all|network"); do +for buildx in $(ls build-*.sh | grep -vE "all|network|pdns"); do echo "Starting build file ${buildx} ..." /bin/bash ${buildx} done diff --git a/build-dovecot.sh b/build-dovecot.sh index 259a334d..4d58c8ca 100755 --- a/build-dovecot.sh +++ b/build-dovecot.sh @@ -5,7 +5,7 @@ source mailcow.conf NAME="dovecot-mailcow" build() { - docker build --no-cache -t dovecot data/Dockerfiles/dovecot/. + docker build --no-cache -t dovecot:local data/Dockerfiles/dovecot/. } if [[ ${1} == "--reconf" ]]; then @@ -23,7 +23,7 @@ if [[ ! -z "$(docker images -q dovecot)" ]]; then read -r -p "Found image locally. Delete local and rebuild without cache anyway? [y/N] " response response=${response,,} if [[ $response =~ ^(yes|y)$ ]]; then - docker rmi dovecot + docker rmi dovecot:local build fi else @@ -45,6 +45,6 @@ docker run \ --network=${DOCKER_NETWORK} \ --network-alias dovecot \ -h ${MAILCOW_HOSTNAME} \ - -d dovecot + -d dovecot:local /bin/bash ./fix-permissions.sh diff --git a/build-pdns.sh b/build-pdns.sh new file mode 100755 index 00000000..7facd965 --- /dev/null +++ b/build-pdns.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +. mailcow.conf + +NAME="pdns-mailcow" + +echo "Stopping and removing containers with name tag ${NAME}..." +if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then + docker stop $(docker ps -af "name=${NAME}" -q) + docker rm $(docker ps -af "name=${NAME}" -q) +fi + +build() { + docker build --no-cache -t pdns data/Dockerfiles/pdns/. +} + +if [[ ! -z "$(docker images -q pdns)" ]]; then + read -r -p "Found image locally. Delete local and rebuild without cache anyway? [y/N] " response + response=${response,,} + if [[ $response =~ ^(yes|y)$ ]]; then + docker rmi pdns + build + fi +else + build +fi + +sed -i "s#allow-from.*#allow-from=127.0.0.0/8 ${DOCKER_SUBNET}#" data/conf/pdns/recursor.conf + +docker run \ + -v ${PWD}/data/conf/pdns/:/etc/powerdns/ \ + --network=${DOCKER_NETWORK} \ + --network-alias pdns \ + -h pdns \ + --name ${NAME} \ + -d pdns diff --git a/build-postfix.sh b/build-postfix.sh index 8906e728..45fc4462 100755 --- a/build-postfix.sh +++ b/build-postfix.sh @@ -4,6 +4,12 @@ NAME="postfix-mailcow" +PDNS_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' pdns-mailcow 2> /dev/null) +if [[ ! ${PDNS_IP} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Cannot determine Powerdns Recursor ip address. Is the container running?" + exit 1 +fi + build() { docker build --no-cache -t postfix data/Dockerfiles/postfix/. } @@ -45,6 +51,8 @@ docker run \ -p ${SUBMISSION_PORT}:587 \ -v ${PWD}/data/conf/postfix:/opt/postfix/conf:ro \ -v ${PWD}/data/assets/ssl:/etc/ssl/mail/:ro \ + --dns=${PDNS_IP} \ + --dns-search=${DOCKER_NETWORK} \ --name ${NAME} \ --network=${DOCKER_NETWORK} \ --network-alias postfix \ diff --git a/build-rspamd.sh b/build-rspamd.sh index bb8a542f..ce214f54 100755 --- a/build-rspamd.sh +++ b/build-rspamd.sh @@ -8,6 +8,12 @@ build() { docker build --no-cache -t rspamd data/Dockerfiles/rspamd/. } +PDNS_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' pdns-mailcow 2> /dev/null) +if [[ ! ${PDNS_IP} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Cannot determine Powerdns Recursor ip address. Is the container running?" + exit 1 +fi + echo "Stopping and removing containers with name tag ${NAME}..." if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then docker stop $(docker ps -af "name=${NAME}" -q) @@ -29,6 +35,8 @@ docker run \ -v ${PWD}/data/conf/rspamd/lua/:/etc/rspamd/lua/ \ -v ${PWD}/data/dkim/txt/:/etc/rspamd/dkim/txt/:ro \ -v ${PWD}/data/dkim/keys/:/etc/rspamd/dkim/keys/:ro \ + --dns=${PDNS_IP} \ + --dns-search=${DOCKER_NETWORK} \ --network=${DOCKER_NETWORK} \ --network-alias rspamd \ -h rspamd \ diff --git a/data/Dockerfiles/pdns/Dockerfile b/data/Dockerfiles/pdns/Dockerfile new file mode 100644 index 00000000..7a37447a --- /dev/null +++ b/data/Dockerfiles/pdns/Dockerfile @@ -0,0 +1,18 @@ +FROM debian:jessie +MAINTAINER Andre Peters + +ENV DEBIAN_FRONTEND noninteractive + +RUN echo 'deb http://repo.powerdns.com/debian jessie-rec-40 main' > /etc/apt/sources.list.d/pdns.list + +RUN echo 'Package: pdns-*\n\ +Pin: origin repo.powerdns.com\n\ +Pin-Priority: 600\n' > /etc/apt/preferences.d/pdns + +RUN apt-key adv --fetch-keys http://repo.powerdns.com/FD380FBB-pub.asc \ + && apt-get update \ + && apt-get install -y --force-yes pdns-recursor + +CMD ["/usr/sbin/pdns_recursor"] + +EXPOSE 53/udp diff --git a/data/conf/nginx/site.conf b/data/conf/nginx/site.conf index 9e07fae9..b84d3112 100644 --- a/data/conf/nginx/site.conf +++ b/data/conf/nginx/site.conf @@ -3,6 +3,11 @@ server { ssl on; ssl_certificate /etc/ssl/mail/mail.crt; ssl_certificate_key /etc/ssl/mail/mail.key; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; + ssl_ecdh_curve secp384r1; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; index index.php index.html; server_name _; error_log /var/log/nginx/error.log; diff --git a/data/conf/pdns/pdns_custom.lua b/data/conf/pdns/pdns_custom.lua new file mode 100644 index 00000000..18588bf2 --- /dev/null +++ b/data/conf/pdns/pdns_custom.lua @@ -0,0 +1 @@ +addNTA("mailcow-network", "nta for local") diff --git a/data/conf/pdns/recursor.conf b/data/conf/pdns/recursor.conf new file mode 100644 index 00000000..ba2534bd --- /dev/null +++ b/data/conf/pdns/recursor.conf @@ -0,0 +1,41 @@ +allow-from=127.0.0.0/8 172.18.0.0/16 +config-dir=/etc/powerdns +daemon=no +disable-syslog=yes +dnssec=process +dnssec-log-bogus=yes +dont-query=10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10, 0.0.0.0/8, 192.0.0.0/24, 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::/96, ::ffff:0:0/96, 100::/64, 2001:db8::/32 +export-etc-hosts=off +# forward-zones= +forward-zones-recurse=mailcow-network.=127.0.0.11 +local-address=0.0.0.0 +local-port=53 +loglevel=6 +# lowercase-outgoing=no +lua-config-file=/etc/powerdns/pdns_custom.lua +# max-cache-entries=1000000 +# max-cache-ttl=86400 +# max-mthreads=2048 +# max-negative-ttl=3600 +# max-packetcache-entries=500000 +# max-qperq=50 +# max-tcp-clients=128 +# max-tcp-per-client=0 +# max-total-msec=7000 +# minimum-ttl-override=0 +# network-timeout=1500 +# packetcache-servfail-ttl=60 +# packetcache-ttl=3600 +quiet=no +# security-poll-suffix=secpoll.powerdns.com. +# serve-rfc1918=yes +# server-down-max-fails=64 +# server-down-throttle-time=60 +setgid=pdns +setuid=pdns +# spoof-nearmiss-max=20 +# stack-size=200000 +# threads=2 +# trace=off +version-string=PowerDNS Recursor +webserver=no diff --git a/data/conf/postfix/main.cf b/data/conf/postfix/main.cf index fbf468d4..3b8dcb32 100644 --- a/data/conf/postfix/main.cf +++ b/data/conf/postfix/main.cf @@ -1,4 +1,4 @@ -myhostname=mail.mailcow.de +myhostname=demo.example.org biff = no append_dot_mydomain = no smtpd_tls_cert_file = /etc/ssl/mail/mail.crt @@ -9,9 +9,9 @@ smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases -myhostname=mail.mailcow.de +myhostname=demo.example.org relayhost = -mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 172.55.0.0/16 +mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 172.55.0.0/16 172.18.0.0/16 mailbox_size_limit = 0 recipient_delimiter = + inet_interfaces = all @@ -50,7 +50,8 @@ smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt smtp_tls_cert_file = /etc/ssl/mail/mail.crt smtp_tls_key_file = /etc/ssl/mail/mail.key smtp_tls_loglevel = 1 -smtp_tls_security_level = may +smtp_dns_support_level = dnssec +smtp_tls_security_level = dane smtpd_data_restrictions = reject_unauth_pipelining, permit smtpd_delay_reject = yes smtpd_error_sleep_time = 10s diff --git a/mailcow.conf b/mailcow.conf index 9b6b84ac..7a0143e8 100644 --- a/mailcow.conf +++ b/mailcow.conf @@ -3,7 +3,7 @@ # Default admin user is "admin" # Default password is "moohoo" -MAILCOW_HOSTNAME=mail.mailcow.de +MAILCOW_HOSTNAME=logs.servercow.de # SQL database configuration DBNAME=mailcow @@ -25,7 +25,7 @@ NGINXVERS="stable" # You should leave that alone # Can also be 11.22.33.44:25 or 0.0.0.0:465 etc. for specific binding -SMTP_PORT=25 +SMTP_PORT=26 SMTPS_PORT=465 SUBMISSION_PORT=587 IMAP_PORT=143 @@ -43,14 +43,3 @@ REDISVERS="latest" DOCKER_NETWORK="mailcow-network" DOCKER_SUBNET="172.18.0.0/16" -# ======= ADVANCED ====== -# - not yet implemented - -# ======================= -# Use existing containers -# ======================= - -# USE_REDIS="container-name-of-exisiting-redis" -# USE_REDIS_NETWORK="docker-network-name-of-existing-redis-container" - -# USE_MEMCACHED="container-name-of-exisiting-memcached" -# USE_MEMCACHED_NETWORK="docker-network-name-of-existing-memcached-container"