[Compose] New images, Nginx checks for SOGo before bootstrapping

[PHP-FPM] Some more modules (primarily for Horde)
[Fail2ban] Do not log matches of local and private ips
[Watchdog] Some changes in log system for further processing (wip)
[ACME] Fixes #745
master
André 2017-11-14 10:44:00 +01:00
parent c2d9928f8f
commit 84a7a1a2e7
5 changed files with 45 additions and 44 deletions

View File

@ -2,6 +2,12 @@
set -o pipefail set -o pipefail
exec 5>&1 exec 5>&1
if [[ "${SKIP_LETS_ENCRYPT}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
log_f "SKIP_LETS_ENCRYPT=y, skipping Let's Encrypt..."
sleep 365d
exec $(readlink -f "$0")
fi
ACME_BASE=/var/lib/acme ACME_BASE=/var/lib/acme
SSL_EXAMPLE=/var/lib/ssl-example SSL_EXAMPLE=/var/lib/ssl-example
@ -102,11 +108,6 @@ while ! mysqladmin ping --host mysql -u${DBUSER} -p${DBPASS} --silent; do
done done
while true; do while true; do
if [[ "${SKIP_LETS_ENCRYPT}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
log_f "SKIP_LETS_ENCRYPT=y, skipping Let's Encrypt..."
sleep 365d
exec $(readlink -f "$0")
fi
if [[ "${SKIP_IP_CHECK}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then if [[ "${SKIP_IP_CHECK}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
SKIP_IP_CHECK=y SKIP_IP_CHECK=y
fi fi

View File

@ -147,6 +147,9 @@ def watch():
result = re.search(rule_regex, item['data']) result = re.search(rule_regex, item['data'])
if result: if result:
addr = result.group(1) addr = result.group(1)
ip = ipaddress.ip_address(addr.decode('ascii'))
if ip.is_private or ip.is_loopback:
continue
print "%s matched rule id %d" % (addr, rule_id) print "%s matched rule id %d" % (addr, rule_id)
log['time'] = int(round(time.time())) log['time'] = int(round(time.time()))
log['priority'] = "warn" log['priority'] = "warn"

View File

@ -32,6 +32,8 @@ RUN apk add -U --no-cache libxml2-dev \
imagemagick-dev \ imagemagick-dev \
imagemagick \ imagemagick \
libtool \ libtool \
gettext-dev \
openldap-dev \
librsvg \ librsvg \
&& pear install channel://pear.php.net/Net_IDNA2-0.2.0 \ && pear install channel://pear.php.net/Net_IDNA2-0.2.0 \
channel://pear.php.net/Auth_SASL-1.1.0 \ channel://pear.php.net/Auth_SASL-1.1.0 \
@ -43,7 +45,7 @@ RUN apk add -U --no-cache libxml2-dev \
&& docker-php-ext-enable redis apcu memcached imagick \ && docker-php-ext-enable redis apcu memcached imagick \
&& pecl clear-cache \ && pecl clear-cache \
&& docker-php-ext-configure intl \ && docker-php-ext-configure intl \
&& docker-php-ext-install -j 4 intl pdo pdo_mysql xmlrpc gd zip pcntl opcache \ && docker-php-ext-install -j 4 intl gettext ldap sockets soap pdo pdo_mysql xmlrpc gd zip pcntl opcache \
&& docker-php-ext-configure imap --with-imap --with-imap-ssl \ && docker-php-ext-configure imap --with-imap --with-imap-ssl \
&& docker-php-ext-install -j 4 imap \ && docker-php-ext-install -j 4 imap \
&& apk del --purge autoconf g++ make libxml2-dev icu-dev imap-dev openssl-dev cyrus-sasl-dev pcre-dev libpng-dev libpng-dev libjpeg-turbo-dev libwebp-dev zlib-dev imagemagick-dev \ && apk del --purge autoconf g++ make libxml2-dev icu-dev imap-dev openssl-dev cyrus-sasl-dev pcre-dev libpng-dev libpng-dev libjpeg-turbo-dev libwebp-dev zlib-dev imagemagick-dev \
@ -55,9 +57,7 @@ RUN apk add -U --no-cache libxml2-dev \
echo 'opcache.memory_consumption=128'; \ echo 'opcache.memory_consumption=128'; \
echo 'opcache.save_comments=1'; \ echo 'opcache.save_comments=1'; \
echo 'opcache.revalidate_freq=1'; \ echo 'opcache.revalidate_freq=1'; \
} > /usr/local/etc/php/conf.d/opcache-recommended.ini \ } > /usr/local/etc/php/conf.d/opcache-recommended.ini
&& rm -rf /usr/src/php*
COPY ./docker-entrypoint.sh / COPY ./docker-entrypoint.sh /

View File

@ -28,13 +28,19 @@ progress() {
[[ ${CURRENT} -gt ${TOTAL} ]] && return [[ ${CURRENT} -gt ${TOTAL} ]] && return
[[ ${CURRENT} -lt 0 ]] && CURRENT=0 [[ ${CURRENT} -lt 0 ]] && CURRENT=0
PERCENT=$(( 200 * ${CURRENT} / ${TOTAL} % 2 + 100 * ${CURRENT} / ${TOTAL} )) PERCENT=$(( 200 * ${CURRENT} / ${TOTAL} % 2 + 100 * ${CURRENT} / ${TOTAL} ))
echo -ne "$(date) - ${SERVICE} health level: \e[7m${PERCENT}%\e[0m (${CURRENT}/${TOTAL}), health trend: " log_msg "${SERVICE} health level: ${PERCENT}% (${CURRENT}/${TOTAL}), health trend: ${DIFF}"
[[ ${DIFF} =~ ^-[1-9] ]] && echo -en '[\e[41m \e[0m] ' || echo -en '[\e[42m \e[0m] ' log_data "$(printf "%d,%d,%d,%d" ${PERCENT} ${CURRENT} ${TOTAL} ${DIFF})" "${SERVICE}"
echo "(${DIFF})"
} }
log_to_redis() { log_msg() {
redis-cli -h redis LPUSH WATCHDOG_LOG "{\"time\":\"$(date +%s)\",\"message\":\"$(printf '%s' "${1}")\"}" redis-cli -h redis LPUSH WATCHDOG_LOG "{\"time\":\"$(date +%s)\",\"message\":\"$(printf '%s' "${1}")\"}" > /dev/null
echo $(date) $(printf '%s\n' "${1}")
}
log_data() {
[[ -z ${1} ]] && return 1
[[ -z ${2} ]] && return 2
redis-cli -h redis LPUSH WATCHDOG_DATA "{\"time\":\"$(date +%s)\",\"service\":\"data\",\"$(printf '%s' "${2}")\":\"$(printf '%s' "${1}")\"}" > /dev/null
} }
function mail_error() { function mail_error() {
@ -43,8 +49,7 @@ function mail_error() {
RCPT_DOMAIN=$(echo ${1} | awk -F @ {'print $NF'}) RCPT_DOMAIN=$(echo ${1} | awk -F @ {'print $NF'})
RCPT_MX=$(dig +short ${RCPT_DOMAIN} mx | sort -n | awk '{print $2; exit}') RCPT_MX=$(dig +short ${RCPT_DOMAIN} mx | sort -n | awk '{print $2; exit}')
if [[ -z ${RCPT_MX} ]]; then if [[ -z ${RCPT_MX} ]]; then
log_to_redis "Cannot determine MX for ${1}, skipping email notification..." log_msg "Cannot determine MX for ${1}, skipping email notification..."
echo "Cannot determine MX for ${1}"
return 1 return 1
fi fi
./smtp-cli --missing-modules-ok \ ./smtp-cli --missing-modules-ok \
@ -54,6 +59,7 @@ function mail_error() {
--from="watchdog@${MAILCOW_HOSTNAME}" \ --from="watchdog@${MAILCOW_HOSTNAME}" \
--server="${RCPT_MX}" \ --server="${RCPT_MX}" \
--hello-host=${MAILCOW_HOSTNAME} --hello-host=${MAILCOW_HOSTNAME}
log_msg "Sent notification email to ${1}"
} }
@ -66,8 +72,8 @@ get_container_ip() {
sleep 1 sleep 1
CONTAINER_ID=$(curl --silent http://dockerapi:8080/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"${1}\")) | .id") CONTAINER_ID=$(curl --silent http://dockerapi:8080/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"${1}\")) | .id")
if [[ ! -z ${CONTAINER_ID} ]]; then if [[ ! -z ${CONTAINER_ID} ]]; then
CONTAINER_IP=$(curl --silent http://dockerapi:8080/containers/${CONTAINER_ID}/json | jq -r '.NetworkSettings.Networks[].IPAddress') CONTAINER_IP=$(curl --silent http://dockerapi:8080/containers/${CONTAINER_ID}/json | jq -r '.NetworkSettings.Networks[].IPAddress')
fi fi
LOOP_C=$((LOOP_C + 1)) LOOP_C=$((LOOP_C + 1))
done done
[[ ${LOOP_C} -gt 5 ]] && echo 240.0.0.0 || echo ${CONTAINER_IP} [[ ${LOOP_C} -gt 5 ]] && echo 240.0.0.0 || echo ${CONTAINER_IP}
@ -253,9 +259,8 @@ dns_checks() {
( (
while true; do while true; do
if ! nginx_checks; then if ! nginx_checks; then
log_to_redis "Nginx hit error limit" log_msg "Nginx hit error limit"
[[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "nginx-mailcow" [[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "nginx-mailcow"
echo -e "\e[31m$(date) - Nginx hit error limit\e[0m"
echo nginx-mailcow > /tmp/com_pipe echo nginx-mailcow > /tmp/com_pipe
fi fi
done done
@ -265,9 +270,8 @@ BACKGROUND_TASKS+=($!)
( (
while true; do while true; do
if ! mysql_checks; then if ! mysql_checks; then
log_to_redis "MySQL hit error limit" log_msg "MySQL hit error limit"
[[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "mysql-mailcow" [[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "mysql-mailcow"
echo -e "\e[31m$(date) - MySQL hit error limit\e[0m"
echo mysql-mailcow > /tmp/com_pipe echo mysql-mailcow > /tmp/com_pipe
fi fi
done done
@ -277,9 +281,8 @@ BACKGROUND_TASKS+=($!)
( (
while true; do while true; do
if ! phpfpm_checks; then if ! phpfpm_checks; then
log_to_redis "PHP-FPM hit error limit" log_msg "PHP-FPM hit error limit"
[[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "php-fpm-mailcow" [[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "php-fpm-mailcow"
echo -e "\e[31m$(date) - PHP-FPM hit error limit\e[0m"
echo php-fpm-mailcow > /tmp/com_pipe echo php-fpm-mailcow > /tmp/com_pipe
fi fi
done done
@ -289,9 +292,8 @@ BACKGROUND_TASKS+=($!)
( (
while true; do while true; do
if ! sogo_checks; then if ! sogo_checks; then
log_to_redis "SOGo hit error limit" log_msg "SOGo hit error limit"
[[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "sogo-mailcow" [[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "sogo-mailcow"
echo -e "\e[31m$(date) - SOGo hit error limit\e[0m"
echo sogo-mailcow > /tmp/com_pipe echo sogo-mailcow > /tmp/com_pipe
fi fi
done done
@ -301,9 +303,8 @@ BACKGROUND_TASKS+=($!)
( (
while true; do while true; do
if ! postfix_checks; then if ! postfix_checks; then
log_to_redis "Postfix hit error limit" log_msg "Postfix hit error limit"
[[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "postfix-mailcow" [[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "postfix-mailcow"
echo -e "\e[31m$(date) - Postfix hit error limit\e[0m"
echo postfix-mailcow > /tmp/com_pipe echo postfix-mailcow > /tmp/com_pipe
fi fi
done done
@ -313,9 +314,8 @@ BACKGROUND_TASKS+=($!)
( (
while true; do while true; do
if ! dovecot_checks; then if ! dovecot_checks; then
log_to_redis "Dovecot hit error limit" log_msg "Dovecot hit error limit"
[[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "dovecot-mailcow" [[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "dovecot-mailcow"
echo -e "\e[31m$(date) - Dovecot hit error limit\e[0m"
echo dovecot-mailcow > /tmp/com_pipe echo dovecot-mailcow > /tmp/com_pipe
fi fi
done done
@ -325,9 +325,8 @@ BACKGROUND_TASKS+=($!)
( (
while true; do while true; do
if ! dns_checks; then if ! dns_checks; then
log_to_redis "Unbound hit error limit" log_msg "Unbound hit error limit"
[[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "unbound-mailcow" [[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "unbound-mailcow"
echo -e "\e[31m$(date) - Unbound hit error limit\e[0m"
#echo unbound-mailcow > /tmp/com_pipe #echo unbound-mailcow > /tmp/com_pipe
fi fi
done done
@ -337,9 +336,8 @@ BACKGROUND_TASKS+=($!)
( (
while true; do while true; do
if ! rspamd_checks; then if ! rspamd_checks; then
log_to_redis "Rspamd hit error limit" log_msg "Rspamd hit error limit"
[[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "rspamd-mailcow" [[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${WATCHDOG_NOTIFY_EMAIL}" "rspamd-mailcow"
echo -e "\e[31m$(date) - Rspamd hit error limit\e[0m"
echo rspamd-mailcow > /tmp/com_pipe echo rspamd-mailcow > /tmp/com_pipe
fi fi
done done
@ -351,8 +349,7 @@ BACKGROUND_TASKS+=($!)
while true; do while true; do
for bg_task in ${BACKGROUND_TASKS[*]}; do for bg_task in ${BACKGROUND_TASKS[*]}; do
if ! kill -0 ${bg_task} 1>&2; then if ! kill -0 ${bg_task} 1>&2; then
echo "Worker ${bg_task} died, stopping watchdog and waiting for respawn..." log_msg "Worker ${bg_task} died, stopping watchdog and waiting for respawn..."
log_to_redis "Worker ${bg_task} died, stopping watchdog and waiting for respawn..."
kill -TERM 1 kill -TERM 1
fi fi
sleep 10 sleep 10
@ -366,7 +363,7 @@ while true; do
while nc -z dockerapi 8080; do while nc -z dockerapi 8080; do
sleep 3 sleep 3
done done
echo "Cannot find dockerapi-mailcow, waiting to recover..." log_msg "Cannot find dockerapi-mailcow, waiting to recover..."
kill -STOP ${BACKGROUND_TASKS[*]} kill -STOP ${BACKGROUND_TASKS[*]}
until nc -z dockerapi 8080; do until nc -z dockerapi 8080; do
sleep 3 sleep 3
@ -385,11 +382,10 @@ while true; do
sleep 3 sleep 3
CONTAINER_ID=$(curl --silent http://dockerapi:8080/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"${com_pipe_answer}\")) | .id") CONTAINER_ID=$(curl --silent http://dockerapi:8080/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"${com_pipe_answer}\")) | .id")
if [[ ! -z ${CONTAINER_ID} ]]; then if [[ ! -z ${CONTAINER_ID} ]]; then
log_to_redis "Sending restart command to ${CONTAINER_ID}..." log_msg "Sending restart command to ${CONTAINER_ID}..."
echo "Sending restart command to ${CONTAINER_ID}..."
curl --silent -XPOST http://dockerapi:8080/containers/${CONTAINER_ID}/restart curl --silent -XPOST http://dockerapi:8080/containers/${CONTAINER_ID}/restart
fi fi
echo "Wait for restarted container to settle and continue watching..." log_msg "Wait for restarted container to settle and continue watching..."
sleep 30s sleep 30s
kill -CONT ${BACKGROUND_TASKS[*]} kill -CONT ${BACKGROUND_TASKS[*]}
kill -USR1 ${BACKGROUND_TASKS[*]} kill -USR1 ${BACKGROUND_TASKS[*]}

View File

@ -92,7 +92,7 @@ services:
- rspamd - rspamd
php-fpm-mailcow: php-fpm-mailcow:
image: mailcow/phpfpm:1.4 image: mailcow/phpfpm:1.5
build: ./data/Dockerfiles/phpfpm build: ./data/Dockerfiles/phpfpm
command: "php-fpm -d date.timezone=${TZ} -d expose_php=0" command: "php-fpm -d date.timezone=${TZ} -d expose_php=0"
depends_on: depends_on:
@ -224,6 +224,7 @@ services:
envsubst < /etc/nginx/conf.d/templates/server_name.template > /etc/nginx/conf.d/server_name.active && envsubst < /etc/nginx/conf.d/templates/server_name.template > /etc/nginx/conf.d/server_name.active &&
nginx -qt && nginx -qt &&
until ping phpfpm -c1 > /dev/null; do sleep 1; done && until ping phpfpm -c1 > /dev/null; do sleep 1; done &&
until ping sogo -c1 > /dev/null; do sleep 1; done &&
until ping redis -c1 > /dev/null; do sleep 1; done && until ping redis -c1 > /dev/null; do sleep 1; done &&
exec nginx -g 'daemon off;'" exec nginx -g 'daemon off;'"
environment: environment:
@ -251,7 +252,7 @@ services:
depends_on: depends_on:
- nginx-mailcow - nginx-mailcow
- mysql-mailcow - mysql-mailcow
image: mailcow/acme:1.22 image: mailcow/acme:1.23
build: ./data/Dockerfiles/acme build: ./data/Dockerfiles/acme
dns: dns:
- 172.22.1.254 - 172.22.1.254
@ -274,7 +275,7 @@ services:
- acme - acme
fail2ban-mailcow: fail2ban-mailcow:
image: mailcow/fail2ban:1.7 image: mailcow/fail2ban:1.8
build: ./data/Dockerfiles/fail2ban build: ./data/Dockerfiles/fail2ban
stop_grace_period: 30s stop_grace_period: 30s
depends_on: depends_on:
@ -295,7 +296,7 @@ services:
- /lib/modules:/lib/modules:ro - /lib/modules:/lib/modules:ro
watchdog-mailcow: watchdog-mailcow:
image: mailcow/watchdog:1.9 image: mailcow/watchdog:1.10
build: ./data/Dockerfiles/watchdog build: ./data/Dockerfiles/watchdog
volumes: volumes:
- vmail-vol-1:/vmail:ro - vmail-vol-1:/vmail:ro