This commit is contained in:
Thomas VIAL 2016-04-21 01:08:14 +02:00
parent a2109ff287
commit b58d0d33d6
13 changed files with 47 additions and 51 deletions

1
.gitignore vendored
View file

@ -3,4 +3,3 @@ docker-compose.yml
postfix/ssl/* postfix/ssl/*
letsencrypt/ letsencrypt/
.idea .idea
config/tmp

View file

@ -34,8 +34,6 @@ RUN (crontab; echo "0 1 * * * /usr/bin/freshclam --quiet") | sort - | uniq - | c
RUN freshclam RUN freshclam
# Configure DKIM (opendkim) # Configure DKIM (opendkim)
RUN mkdir -p /etc/opendkim/keys
ADD target/opendkim/TrustedHosts /etc/opendkim/TrustedHosts
# DKIM config files # DKIM config files
ADD target/opendkim/opendkim.conf /etc/opendkim.conf ADD target/opendkim/opendkim.conf /etc/opendkim.conf
ADD target/opendkim/default-opendkim /etc/default/opendkim ADD target/opendkim/default-opendkim /etc/default/opendkim

View file

@ -15,8 +15,7 @@ run:
# Run containers # Run containers
docker run -d --name mail \ docker run -d --name mail \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test/config/test-opendkim":/tmp/docker-mailserver/opendkim \ -v "`pwd`/test":/tmp/docker-mailserver-test \
-v "`pwd`/test":/tmp/docker-mailserver/test \
-e SA_TAG=1.0 \ -e SA_TAG=1.0 \
-e SA_TAG2=2.0 \ -e SA_TAG2=2.0 \
-e SA_KILL=3.0 \ -e SA_KILL=3.0 \
@ -25,19 +24,19 @@ run:
sleep 15 sleep 15
docker run -d --name mail_pop3 \ docker run -d --name mail_pop3 \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test":/tmp/docker-mailserver/test \ -v "`pwd`/test":/tmp/docker-mailserver-test \
-e ENABLE_POP3=1 \ -e ENABLE_POP3=1 \
-h mail.my-domain.com -t $(NAME) -h mail.my-domain.com -t $(NAME)
sleep 15 sleep 15
docker run -d --name mail_smtponly \ docker run -d --name mail_smtponly \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test":/tmp/docker-mailserver/test \ -v "`pwd`/test":/tmp/docker-mailserver-test \
-e SMTP_ONLY=1 \ -e SMTP_ONLY=1 \
-h mail.my-domain.com -t $(NAME) -h mail.my-domain.com -t $(NAME)
sleep 15 sleep 15
docker run -d --name mail_fail2ban \ docker run -d --name mail_fail2ban \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test":/tmp/docker-mailserver/test \ -v "`pwd`/test":/tmp/docker-mailserver-test \
-e ENABLE_FAIL2BAN=1 \ -e ENABLE_FAIL2BAN=1 \
-h mail.my-domain.com -t $(NAME) -h mail.my-domain.com -t $(NAME)
# Wait for containers to fully start # Wait for containers to fully start
@ -45,12 +44,12 @@ run:
fixtures: fixtures:
# Sending test mails # Sending test mails
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver/test/email-templates/amavis-spam.txt" docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-spam.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver/test/email-templates/amavis-virus.txt" docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-virus.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver/test/email-templates/existing-alias-external.txt" docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-alias-external.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver/test/email-templates/existing-alias-local.txt" docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-alias-local.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver/test/email-templates/existing-user.txt" docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver/test/email-templates/non-existing-user.txt" docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/non-existing-user.txt"
# Wait for mails to be analyzed # Wait for mails to be analyzed
sleep 10 sleep 10
@ -61,4 +60,4 @@ tests:
clean: clean:
# Remove running test containers # Remove running test containers
docker rm -f mail mail_pop3 mail_smtponly mail_fail2ban fail-auth-mailer docker rm -f mail mail_pop3 mail_smtponly mail_fail2ban fail-auth-mailer
rm -rf config/opendkim config/test-opendkim config/tmp rm -rf "$(pwd)/test/config/empty" && mkdir -p "$(pwd)/test/config/empty"

View file

@ -1,10 +1,12 @@
#!/bin/sh #!/bin/sh
touch /tmp/vhost.tmp
# Getting domains from mail accounts # Getting domains from mail accounts
while IFS=$'|' read login pass while IFS=$'|' read login pass
do do
domain=$(echo ${login} | cut -d @ -f2) domain=$(echo ${login} | cut -d @ -f2)
echo ${domain} >> /tmp/docker-mailserver/tmp/vhost.tmp echo ${domain} >> /tmp/vhost.tmp
done < /tmp/docker-mailserver/postfix-accounts.cf done < /tmp/docker-mailserver/postfix-accounts.cf
# Getting domains from mail aliases # Getting domains from mail aliases
@ -14,15 +16,15 @@ do
uname=$(echo ${from} | cut -d @ -f1) uname=$(echo ${from} | cut -d @ -f1)
domain=$(echo ${from} | cut -d @ -f2) domain=$(echo ${from} | cut -d @ -f2)
# if they are equal it means the line looks like: "user1 other@domain.tld" # if they are equal it means the line looks like: "user1 other@domain.tld"
test "$uname" != "$domain" && echo ${domain} >> /tmp/docker-mailserver/tmp/vhost.tmp test "$uname" != "$domain" && echo ${domain} >> /tmp/vhost.tmp
done < /tmp/docker-mailserver/postfix-virtual.cf done < /tmp/docker-mailserver/postfix-virtual.cf
# Keeping unique entries # Keeping unique entries
if [ -f /tmp/docker-mailserver/tmp/vhost.tmp ]; then if [ -f /tmp/vhost.tmp ]; then
cat /tmp/docker-mailserver/tmp/vhost.tmp | sort | uniq > /etc/postfix/vhost && rm /tmp/docker-mailserver/tmp/vhost.tmp cat /tmp/vhost.tmp | sort | uniq > /tmp/vhost && rm /tmp/vhost.tmp
fi fi
grep -vE '^(\s*$|#)' /etc/postfix/vhost | while read domainname; do grep -vE '^(\s*$|#)' /tmp/vhost | while read domainname; do
mkdir -p /tmp/docker-mailserver/opendkim/keys/$domainname mkdir -p /tmp/docker-mailserver/opendkim/keys/$domainname
if [ ! -f "/tmp/docker-mailserver/opendkim/keys/$domainname/mail.private" ]; then if [ ! -f "/tmp/docker-mailserver/opendkim/keys/$domainname/mail.private" ]; then
@ -53,3 +55,10 @@ grep -vE '^(\s*$|#)' /etc/postfix/vhost | while read domainname; do
fi fi
done done
# Creates TrustedHosts if missing
if [ ! -f "/tmp/docker-mailserver/opendkim/TrustedHosts" ]; then
echo "Creating DKIM TrustedHosts";
echo "127.0.0.1" > /tmp/docker-mailserver/opendkim/TrustedHosts
echo "localhost" >> /tmp/docker-mailserver/opendkim/TrustedHosts
fi

View file

@ -5,12 +5,6 @@ die () {
exit 1 exit 1
} }
#
# Preparing
#
mkdir -p /tmp/docker-mailserver/tmp
# #
# Users # Users
# #
@ -57,7 +51,7 @@ if [ -f /tmp/docker-mailserver/postfix-accounts.cf ]; then
touch "/var/mail/${domain}/${user}/.Sent/maildirfolder" touch "/var/mail/${domain}/${user}/.Sent/maildirfolder"
fi fi
echo ${domain} >> /tmp/docker-mailserver/tmp/vhost.tmp echo ${domain} >> /tmp/vhost.tmp
done < /tmp/docker-mailserver/postfix-accounts.cf done < /tmp/docker-mailserver/postfix-accounts.cf
else else
echo "==> Warning: 'config/docker-mailserver/postfix-accounts.cf' is not provided. No mail account created." echo "==> Warning: 'config/docker-mailserver/postfix-accounts.cf' is not provided. No mail account created."
@ -75,14 +69,14 @@ if [ -f /tmp/docker-mailserver/postfix-virtual.cf ]; then
uname=$(echo ${from} | cut -d @ -f1) uname=$(echo ${from} | cut -d @ -f1)
domain=$(echo ${from} | cut -d @ -f2) domain=$(echo ${from} | cut -d @ -f2)
# if they are equal it means the line looks like: "user1 other@domain.tld" # if they are equal it means the line looks like: "user1 other@domain.tld"
test "$uname" != "$domain" && echo ${domain} >> /tmp/docker-mailserver/tmp/vhost.tmp test "$uname" != "$domain" && echo ${domain} >> /tmp/vhost.tmp
done < /tmp/docker-mailserver/postfix-virtual.cf done < /tmp/docker-mailserver/postfix-virtual.cf
else else
echo "==> Warning: 'config/postfix-virtual.cf' is not provided. No mail alias/forward created." echo "==> Warning: 'config/postfix-virtual.cf' is not provided. No mail alias/forward created."
fi fi
if [ -f /tmp/docker-mailserver/tmp/vhost.tmp ]; then if [ -f /tmp/vhost.tmp ]; then
cat /tmp/docker-mailserver/tmp/vhost.tmp | sort | uniq > /etc/postfix/vhost && rm /tmp/docker-mailserver/tmp/vhost.tmp cat /tmp/vhost.tmp | sort | uniq > /etc/postfix/vhost && rm /tmp/vhost.tmp
fi fi
echo "Postfix configurations" echo "Postfix configurations"

View file

@ -57,7 +57,7 @@
} }
@test "checking imap: authentication works" { @test "checking imap: authentication works" {
run docker exec mail /bin/sh -c "nc -w 1 0.0.0.0 143 < /tmp/docker-mailserver/test/auth/imap-auth.txt" run docker exec mail /bin/sh -c "nc -w 1 0.0.0.0 143 < /tmp/docker-mailserver-test/auth/imap-auth.txt"
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
} }
@ -71,7 +71,7 @@
} }
@test "checking pop: authentication works" { @test "checking pop: authentication works" {
run docker exec mail_pop3 /bin/sh -c "nc -w 1 0.0.0.0 110 < /tmp/docker-mailserver/test/auth/pop3-auth.txt" run docker exec mail_pop3 /bin/sh -c "nc -w 1 0.0.0.0 110 < /tmp/docker-mailserver-test/auth/pop3-auth.txt"
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
} }
@ -109,22 +109,22 @@
# #
@test "checking smtp: authentication works with good password (plain)" { @test "checking smtp: authentication works with good password (plain)" {
run docker exec mail /bin/sh -c "nc -w 5 0.0.0.0 25 < /tmp/docker-mailserver/test/auth/smtp-auth-plain.txt | grep 'Authentication successful'" run docker exec mail /bin/sh -c "nc -w 5 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/smtp-auth-plain.txt | grep 'Authentication successful'"
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
} }
@test "checking smtp: authentication fails with wrong password (plain)" { @test "checking smtp: authentication fails with wrong password (plain)" {
run docker exec mail /bin/sh -c "nc -w 20 0.0.0.0 25 < /tmp/docker-mailserver/test/auth/smtp-auth-plain-wrong.txt | grep 'authentication failed'" run docker exec mail /bin/sh -c "nc -w 20 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/smtp-auth-plain-wrong.txt | grep 'authentication failed'"
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
} }
@test "checking smtp: authentication works with good password (login)" { @test "checking smtp: authentication works with good password (login)" {
run docker exec mail /bin/sh -c "nc -w 5 0.0.0.0 25 < /tmp/docker-mailserver/test/auth/smtp-auth-login.txt | grep 'Authentication successful'" run docker exec mail /bin/sh -c "nc -w 5 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/smtp-auth-login.txt | grep 'Authentication successful'"
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
} }
@test "checking smtp: authentication fails with wrong password (login)" { @test "checking smtp: authentication fails with wrong password (login)" {
run docker exec mail /bin/sh -c "nc -w 20 0.0.0.0 25 < /tmp/docker-mailserver/test/auth/smtp-auth-login-wrong.txt | grep 'authentication failed'" run docker exec mail /bin/sh -c "nc -w 20 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/smtp-auth-login-wrong.txt | grep 'authentication failed'"
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
} }
@ -249,18 +249,15 @@
[ "$output" -eq 2 ] [ "$output" -eq 2 ]
} }
@test "checking opendkim: /etc/opendkim/KeyTable should not exist because not provided" { @test "checking opendkim: generator creates keys, tables and TrustedHosts" {
run docker exec mail_smtponly /bin/sh -c "cat /etc/opendkim/KeyTable"
[ "$status" -eq 1 ]
}
@test "checking opendkim: generator works as expected" {
run docker run --rm \ run docker run --rm \
-v "$(pwd)/config":/tmp/docker-mailserver \ -v "$(pwd)/test/config/empty/":/tmp/docker-mailserver/ \
-v "$(pwd)/config/test-opendkim":/tmp/docker-mailserver/opendkim \ -v "$(pwd)/test/config/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \
-v "$(pwd)/test/config/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \
-ti tvial/docker-mailserver:v2 generate-dkim-config | wc -l -ti tvial/docker-mailserver:v2 generate-dkim-config | wc -l
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
[ "$output" -eq 4 ] [ "$output" -eq 5 ]
rm -rf "$(pwd)/test/config/empty" && mkdir -p "$(pwd)/test/config/empty"
} }
# #
@ -317,12 +314,12 @@
# Getting mail_fail2ban container IP # Getting mail_fail2ban container IP
MAIL_FAIL2BAN_IP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' mail_fail2ban) MAIL_FAIL2BAN_IP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' mail_fail2ban)
# Create a container which will send wront authentications and should banned # Create a container which will send wront authentications and should banned
docker run --name fail-auth-mailer -e MAIL_FAIL2BAN_IP=$MAIL_FAIL2BAN_IP -v "$(pwd)/test":/tmp/docker-mailserver/test -d tvial/docker-mailserver:v2 tail -f /var/log/faillog docker run --name fail-auth-mailer -e MAIL_FAIL2BAN_IP=$MAIL_FAIL2BAN_IP -v "$(pwd)/test":/tmp/docker-mailserver-test -d tvial/docker-mailserver:v2 tail -f /var/log/faillog
docker exec fail-auth-mailer /bin/sh -c 'nc $MAIL_FAIL2BAN_IP 25 < /tmp/docker-mailserver/test/auth/smtp-auth-login-wrong.txt' docker exec fail-auth-mailer /bin/sh -c 'nc $MAIL_FAIL2BAN_IP 25 < /tmp/docker-mailserver-test/auth/smtp-auth-login-wrong.txt'
docker exec fail-auth-mailer /bin/sh -c 'nc $MAIL_FAIL2BAN_IP 25 < /tmp/docker-mailserver/test/auth/smtp-auth-login-wrong.txt' docker exec fail-auth-mailer /bin/sh -c 'nc $MAIL_FAIL2BAN_IP 25 < /tmp/docker-mailserver-test/auth/smtp-auth-login-wrong.txt'
docker exec fail-auth-mailer /bin/sh -c 'nc $MAIL_FAIL2BAN_IP 25 < /tmp/docker-mailserver/test/auth/smtp-auth-login-wrong.txt' docker exec fail-auth-mailer /bin/sh -c 'nc $MAIL_FAIL2BAN_IP 25 < /tmp/docker-mailserver-test/auth/smtp-auth-login-wrong.txt'
docker exec fail-auth-mailer /bin/sh -c 'nc $MAIL_FAIL2BAN_IP 25 < /tmp/docker-mailserver/test/auth/smtp-auth-login-wrong.txt' docker exec fail-auth-mailer /bin/sh -c 'nc $MAIL_FAIL2BAN_IP 25 < /tmp/docker-mailserver-test/auth/smtp-auth-login-wrong.txt'
docker exec fail-auth-mailer /bin/sh -c 'nc $MAIL_FAIL2BAN_IP 25 < /tmp/docker-mailserver/test/auth/smtp-auth-login-wrong.txt' docker exec fail-auth-mailer /bin/sh -c 'nc $MAIL_FAIL2BAN_IP 25 < /tmp/docker-mailserver-test/auth/smtp-auth-login-wrong.txt'
sleep 5 sleep 5
# Checking that FAIL_AUTH_MAILER_IP is banned in mail_fail2ban # Checking that FAIL_AUTH_MAILER_IP is banned in mail_fail2ban
FAIL_AUTH_MAILER_IP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' fail-auth-mailer) FAIL_AUTH_MAILER_IP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' fail-auth-mailer)