Просмотр исходного кода

[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

André 7 лет назад
Родитель
Сommit
84a7a1a2e7

+ 6 - 5
data/Dockerfiles/acme/docker-entrypoint.sh

@@ -2,6 +2,12 @@
 set -o pipefail
 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
 SSL_EXAMPLE=/var/lib/ssl-example
 
@@ -102,11 +108,6 @@ while ! mysqladmin ping --host mysql -u${DBUSER} -p${DBPASS} --silent; do
 done
 
 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
     SKIP_IP_CHECK=y
   fi

+ 3 - 0
data/Dockerfiles/fail2ban/logwatch.py

@@ -147,6 +147,9 @@ def watch():
 					result = re.search(rule_regex, item['data'])
 					if result:
 						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)
 						log['time'] = int(round(time.time()))
 						log['priority'] = "warn"

+ 4 - 4
data/Dockerfiles/phpfpm/Dockerfile

@@ -32,6 +32,8 @@ RUN apk add -U --no-cache libxml2-dev \
   imagemagick-dev \
   imagemagick \
   libtool \
+  gettext-dev \
+  openldap-dev \
   librsvg \
   && pear install channel://pear.php.net/Net_IDNA2-0.2.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 \
 	&& pecl clear-cache \
 	&& 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-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 \
@@ -55,9 +57,7 @@ RUN apk add -U --no-cache libxml2-dev \
   echo 'opcache.memory_consumption=128'; \
   echo 'opcache.save_comments=1'; \
   echo 'opcache.revalidate_freq=1'; \
-} > /usr/local/etc/php/conf.d/opcache-recommended.ini \
-  && rm -rf /usr/src/php*
-
+} > /usr/local/etc/php/conf.d/opcache-recommended.ini
 
 COPY ./docker-entrypoint.sh /
 

+ 27 - 31
data/Dockerfiles/watchdog/watchdog.sh

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

+ 5 - 4
docker-compose.yml

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