public
nobgit
read
NobMail
Based on mailcow: dockerized
Languages
Repository composition by tracked source files.
PHP
49%
JavaScript
35%
HTML
9%
CSS
4%
Shell
2%
Python
1%
Lua
0%
Perl
0%
Ruby
0%
SCSS
0%
Create file
Wiki Documentation
Clone
https://nobgit.com/orgs/nobgit/nobmail.git
ssh://[email protected]:2222/orgs/nobgit/nobmail.git
Commit
Add pdns resolver, changed some other files
47a51663
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
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`.
+
+## 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 [email protected] \
+ --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
+```
-## Usage
+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 <[email protected]>
+
+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"