mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2025-12-15 02:46:00 +00:00
Merge branch 'staging' into nightly
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
FROM alpine:3.20
|
FROM alpine:3.20
|
||||||
|
|
||||||
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
|
||||||
|
|
||||||
|
|
||||||
RUN apk upgrade --no-cache \
|
RUN apk upgrade --no-cache \
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ done
|
|||||||
log_f "Database OK"
|
log_f "Database OK"
|
||||||
|
|
||||||
log_f "Waiting for Nginx..."
|
log_f "Waiting for Nginx..."
|
||||||
until $(curl --output /dev/null --silent --head --fail http://nginx:8081); do
|
until $(curl --output /dev/null --silent --head --fail http://nginx.${COMPOSE_PROJECT_NAME}_mailcow-network:8081); do
|
||||||
sleep 2
|
sleep 2
|
||||||
done
|
done
|
||||||
log_f "Nginx OK"
|
log_f "Nginx OK"
|
||||||
@@ -137,7 +137,7 @@ log_f "Resolver OK"
|
|||||||
# Waiting for domain table
|
# Waiting for domain table
|
||||||
log_f "Waiting for domain table..."
|
log_f "Waiting for domain table..."
|
||||||
while [[ -z ${DOMAIN_TABLE} ]]; do
|
while [[ -z ${DOMAIN_TABLE} ]]; do
|
||||||
curl --silent http://nginx/ >/dev/null 2>&1
|
curl --silent http://nginx.${COMPOSE_PROJECT_NAME}_mailcow-network/ >/dev/null 2>&1
|
||||||
DOMAIN_TABLE=$(mysql --socket=/var/run/mysqld/mysqld.sock -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "SHOW TABLES LIKE 'domain'" -Bs)
|
DOMAIN_TABLE=$(mysql --socket=/var/run/mysqld/mysqld.sock -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "SHOW TABLES LIKE 'domain'" -Bs)
|
||||||
[[ -z ${DOMAIN_TABLE} ]] && sleep 10
|
[[ -z ${DOMAIN_TABLE} ]] && sleep 10
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -2,32 +2,32 @@
|
|||||||
|
|
||||||
# Reading container IDs
|
# Reading container IDs
|
||||||
# Wrapping as array to ensure trimmed content when calling $NGINX etc.
|
# Wrapping as array to ensure trimmed content when calling $NGINX etc.
|
||||||
NGINX=($(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"nginx-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" | tr "\n" " "))
|
NGINX=($(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"nginx-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" | tr "\n" " "))
|
||||||
DOVECOT=($(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"dovecot-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" | tr "\n" " "))
|
DOVECOT=($(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"dovecot-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" | tr "\n" " "))
|
||||||
POSTFIX=($(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"postfix-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" | tr "\n" " "))
|
POSTFIX=($(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"postfix-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" | tr "\n" " "))
|
||||||
|
|
||||||
reload_nginx(){
|
reload_nginx(){
|
||||||
echo "Reloading Nginx..."
|
echo "Reloading Nginx..."
|
||||||
NGINX_RELOAD_RET=$(curl -X POST --insecure https://dockerapi/containers/${NGINX}/exec -d '{"cmd":"reload", "task":"nginx"}' --silent -H 'Content-type: application/json' | jq -r .type)
|
NGINX_RELOAD_RET=$(curl -X POST --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${NGINX}/exec -d '{"cmd":"reload", "task":"nginx"}' --silent -H 'Content-type: application/json' | jq -r .type)
|
||||||
[[ ${NGINX_RELOAD_RET} != 'success' ]] && { echo "Could not reload Nginx, restarting container..."; restart_container ${NGINX} ; }
|
[[ ${NGINX_RELOAD_RET} != 'success' ]] && { echo "Could not reload Nginx, restarting container..."; restart_container ${NGINX} ; }
|
||||||
}
|
}
|
||||||
|
|
||||||
reload_dovecot(){
|
reload_dovecot(){
|
||||||
echo "Reloading Dovecot..."
|
echo "Reloading Dovecot..."
|
||||||
DOVECOT_RELOAD_RET=$(curl -X POST --insecure https://dockerapi/containers/${DOVECOT}/exec -d '{"cmd":"reload", "task":"dovecot"}' --silent -H 'Content-type: application/json' | jq -r .type)
|
DOVECOT_RELOAD_RET=$(curl -X POST --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${DOVECOT}/exec -d '{"cmd":"reload", "task":"dovecot"}' --silent -H 'Content-type: application/json' | jq -r .type)
|
||||||
[[ ${DOVECOT_RELOAD_RET} != 'success' ]] && { echo "Could not reload Dovecot, restarting container..."; restart_container ${DOVECOT} ; }
|
[[ ${DOVECOT_RELOAD_RET} != 'success' ]] && { echo "Could not reload Dovecot, restarting container..."; restart_container ${DOVECOT} ; }
|
||||||
}
|
}
|
||||||
|
|
||||||
reload_postfix(){
|
reload_postfix(){
|
||||||
echo "Reloading Postfix..."
|
echo "Reloading Postfix..."
|
||||||
POSTFIX_RELOAD_RET=$(curl -X POST --insecure https://dockerapi/containers/${POSTFIX}/exec -d '{"cmd":"reload", "task":"postfix"}' --silent -H 'Content-type: application/json' | jq -r .type)
|
POSTFIX_RELOAD_RET=$(curl -X POST --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${POSTFIX}/exec -d '{"cmd":"reload", "task":"postfix"}' --silent -H 'Content-type: application/json' | jq -r .type)
|
||||||
[[ ${POSTFIX_RELOAD_RET} != 'success' ]] && { echo "Could not reload Postfix, restarting container..."; restart_container ${POSTFIX} ; }
|
[[ ${POSTFIX_RELOAD_RET} != 'success' ]] && { echo "Could not reload Postfix, restarting container..."; restart_container ${POSTFIX} ; }
|
||||||
}
|
}
|
||||||
|
|
||||||
restart_container(){
|
restart_container(){
|
||||||
for container in $*; do
|
for container in $*; do
|
||||||
echo "Restarting ${container}..."
|
echo "Restarting ${container}..."
|
||||||
C_REST_OUT=$(curl -X POST --insecure https://dockerapi/containers/${container}/restart --silent | jq -r '.msg')
|
C_REST_OUT=$(curl -X POST --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${container}/restart --silent | jq -r '.msg')
|
||||||
echo "${C_REST_OUT}"
|
echo "${C_REST_OUT}"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
FROM alpine:3.20
|
FROM alpine:3.20
|
||||||
|
|
||||||
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
|
||||||
|
|
||||||
RUN apk upgrade --no-cache \
|
RUN apk upgrade --no-cache \
|
||||||
&& apk add --update --no-cache \
|
&& apk add --update --no-cache \
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
FROM alpine:3.20
|
FROM alpine:3.20
|
||||||
|
|
||||||
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
|
||||||
|
|
||||||
ARG PIP_BREAK_SYSTEM_PACKAGES=1
|
ARG PIP_BREAK_SYSTEM_PACKAGES=1
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
FROM alpine:3.20
|
FROM alpine:3.20
|
||||||
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
|
||||||
|
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
|
||||||
|
|
||||||
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^(?<version>.*)$
|
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^(?<version>.*)$
|
||||||
ARG GOSU_VERSION=1.16
|
ARG GOSU_VERSION=1.16
|
||||||
|
|||||||
@@ -283,14 +283,6 @@ sievec /var/vmail/sieve/global_sieve_after.sieve
|
|||||||
sievec /usr/lib/dovecot/sieve/report-spam.sieve
|
sievec /usr/lib/dovecot/sieve/report-spam.sieve
|
||||||
sievec /usr/lib/dovecot/sieve/report-ham.sieve
|
sievec /usr/lib/dovecot/sieve/report-ham.sieve
|
||||||
|
|
||||||
for file in /var/vmail/*/*/sieve/*.sieve ; do
|
|
||||||
if [[ "$file" == "/var/vmail/*/*/sieve/*.sieve" ]]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
sievec "$file" "$(dirname "$file")/../.dovecot.svbin"
|
|
||||||
chown vmail:vmail "$(dirname "$file")/../.dovecot.svbin"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Fix permissions
|
# Fix permissions
|
||||||
chown root:root /etc/dovecot/sql/*.conf
|
chown root:root /etc/dovecot/sql/*.conf
|
||||||
chown root:dovecot /etc/dovecot/sql/dovecot-dict-sql-sieve* /etc/dovecot/sql/dovecot-dict-sql-quota* /etc/dovecot/auth/passwd-verify.lua
|
chown root:dovecot /etc/dovecot/sql/dovecot-dict-sql-sieve* /etc/dovecot/sql/dovecot-dict-sql-quota* /etc/dovecot/auth/passwd-verify.lua
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ FILE=/tmp/mail$$
|
|||||||
cat > $FILE
|
cat > $FILE
|
||||||
trap "/bin/rm -f $FILE" 0 1 2 3 13 15
|
trap "/bin/rm -f $FILE" 0 1 2 3 13 15
|
||||||
|
|
||||||
cat ${FILE} | /usr/bin/curl -H "Flag: 11" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/fuzzydel
|
cat ${FILE} | /usr/bin/curl -H "Flag: 11" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/fuzzydel
|
||||||
cat ${FILE} | /usr/bin/curl -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/learnham
|
cat ${FILE} | /usr/bin/curl -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/learnham
|
||||||
cat ${FILE} | /usr/bin/curl -H "Flag: 13" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/fuzzyadd
|
cat ${FILE} | /usr/bin/curl -H "Flag: 13" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/fuzzyadd
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ FILE=/tmp/mail$$
|
|||||||
cat > $FILE
|
cat > $FILE
|
||||||
trap "/bin/rm -f $FILE" 0 1 2 3 13 15
|
trap "/bin/rm -f $FILE" 0 1 2 3 13 15
|
||||||
|
|
||||||
cat ${FILE} | /usr/bin/curl -H "Flag: 13" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/fuzzydel
|
cat ${FILE} | /usr/bin/curl -H "Flag: 13" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/fuzzydel
|
||||||
cat ${FILE} | /usr/bin/curl -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/learnspam
|
cat ${FILE} | /usr/bin/curl -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/learnspam
|
||||||
cat ${FILE} | /usr/bin/curl -H "Flag: 11" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/fuzzyadd
|
cat ${FILE} | /usr/bin/curl -H "Flag: 11" -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/fuzzyadd
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ sed -i -e 's/\([^\\]\)\$\([^\/]\)/\1\\$\2/g' /etc/rspamd/custom/sa-rules
|
|||||||
|
|
||||||
if [[ "$(cat /etc/rspamd/custom/sa-rules | md5sum | cut -d' ' -f1)" != "${HASH_SA_RULES}" ]]; then
|
if [[ "$(cat /etc/rspamd/custom/sa-rules | md5sum | cut -d' ' -f1)" != "${HASH_SA_RULES}" ]]; then
|
||||||
CONTAINER_NAME=rspamd-mailcow
|
CONTAINER_NAME=rspamd-mailcow
|
||||||
CONTAINER_ID=$(curl --silent --insecure https://dockerapi/containers/json | \
|
CONTAINER_ID=$(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | \
|
||||||
jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | \
|
jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | \
|
||||||
jq -rc "select( .name | tostring | contains(\"${CONTAINER_NAME}\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id")
|
jq -rc "select( .name | tostring | contains(\"${CONTAINER_NAME}\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id")
|
||||||
if [[ ! -z ${CONTAINER_ID} ]]; then
|
if [[ ! -z ${CONTAINER_ID} ]]; then
|
||||||
curl --silent --insecure -XPOST --connect-timeout 15 --max-time 120 https://dockerapi/containers/${CONTAINER_ID}/restart
|
curl --silent --insecure -XPOST --connect-timeout 15 --max-time 120 https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${CONTAINER_ID}/restart
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
FROM alpine:3.20
|
FROM alpine:3.20
|
||||||
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
|
||||||
|
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
FROM alpine:3.20
|
FROM alpine:3.20
|
||||||
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
|
||||||
|
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
|
||||||
|
|
||||||
ARG PIP_BREAK_SYSTEM_PACKAGES=1
|
ARG PIP_BREAK_SYSTEM_PACKAGES=1
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
FROM php:8.2-fpm-alpine3.18
|
FROM php:8.2-fpm-alpine3.18
|
||||||
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
|
||||||
|
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
|
||||||
|
|
||||||
# renovate: datasource=github-tags depName=krakjoe/apcu versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
# renovate: datasource=github-tags depName=krakjoe/apcu versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
||||||
ARG APCU_PECL_VERSION=5.1.23
|
ARG APCU_PECL_VERSION=5.1.23
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ done
|
|||||||
# Check mysql_upgrade (master and slave)
|
# Check mysql_upgrade (master and slave)
|
||||||
CONTAINER_ID=
|
CONTAINER_ID=
|
||||||
until [[ ! -z "${CONTAINER_ID}" ]] && [[ "${CONTAINER_ID}" =~ ^[[:alnum:]]*$ ]]; do
|
until [[ ! -z "${CONTAINER_ID}" ]] && [[ "${CONTAINER_ID}" =~ ^[[:alnum:]]*$ ]]; do
|
||||||
CONTAINER_ID=$(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" 2> /dev/null | jq -rc "select( .name | tostring | contains(\"mysql-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" 2> /dev/null)
|
CONTAINER_ID=$(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" 2> /dev/null | jq -rc "select( .name | tostring | contains(\"mysql-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" 2> /dev/null)
|
||||||
echo "Could not get mysql-mailcow container id... trying again"
|
echo "Could not get mysql-mailcow container id... trying again"
|
||||||
sleep 2
|
sleep 2
|
||||||
done
|
done
|
||||||
@@ -35,7 +35,7 @@ until [[ ${SQL_UPGRADE_STATUS} == 'success' ]]; do
|
|||||||
echo "Tried to upgrade MySQL and failed, giving up after ${SQL_LOOP_C} retries and starting container (oops, not good)"
|
echo "Tried to upgrade MySQL and failed, giving up after ${SQL_LOOP_C} retries and starting container (oops, not good)"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
SQL_FULL_UPGRADE_RETURN=$(curl --silent --insecure -XPOST https://dockerapi/containers/${CONTAINER_ID}/exec -d '{"cmd":"system", "task":"mysql_upgrade"}' --silent -H 'Content-type: application/json')
|
SQL_FULL_UPGRADE_RETURN=$(curl --silent --insecure -XPOST https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${CONTAINER_ID}/exec -d '{"cmd":"system", "task":"mysql_upgrade"}' --silent -H 'Content-type: application/json')
|
||||||
SQL_UPGRADE_STATUS=$(echo ${SQL_FULL_UPGRADE_RETURN} | jq -r .type)
|
SQL_UPGRADE_STATUS=$(echo ${SQL_FULL_UPGRADE_RETURN} | jq -r .type)
|
||||||
SQL_LOOP_C=$((SQL_LOOP_C+1))
|
SQL_LOOP_C=$((SQL_LOOP_C+1))
|
||||||
echo "SQL upgrade iteration #${SQL_LOOP_C}"
|
echo "SQL upgrade iteration #${SQL_LOOP_C}"
|
||||||
@@ -60,12 +60,12 @@ done
|
|||||||
|
|
||||||
# doing post-installation stuff, if SQL was upgraded (master and slave)
|
# doing post-installation stuff, if SQL was upgraded (master and slave)
|
||||||
if [ ${SQL_CHANGED} -eq 1 ]; then
|
if [ ${SQL_CHANGED} -eq 1 ]; then
|
||||||
POSTFIX=$(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" 2> /dev/null | jq -rc "select( .name | tostring | contains(\"postfix-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" 2> /dev/null)
|
POSTFIX=$(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" 2> /dev/null | jq -rc "select( .name | tostring | contains(\"postfix-mailcow\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id" 2> /dev/null)
|
||||||
if [[ -z "${POSTFIX}" ]] || ! [[ "${POSTFIX}" =~ ^[[:alnum:]]*$ ]]; then
|
if [[ -z "${POSTFIX}" ]] || ! [[ "${POSTFIX}" =~ ^[[:alnum:]]*$ ]]; then
|
||||||
echo "Could not determine Postfix container ID, skipping Postfix restart."
|
echo "Could not determine Postfix container ID, skipping Postfix restart."
|
||||||
else
|
else
|
||||||
echo "Restarting Postfix"
|
echo "Restarting Postfix"
|
||||||
curl -X POST --silent --insecure https://dockerapi/containers/${POSTFIX}/restart | jq -r '.msg'
|
curl -X POST --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${POSTFIX}/restart | jq -r '.msg'
|
||||||
echo "Sleeping 5 seconds..."
|
echo "Sleeping 5 seconds..."
|
||||||
sleep 5
|
sleep 5
|
||||||
fi
|
fi
|
||||||
@@ -74,7 +74,7 @@ fi
|
|||||||
# Check mysql tz import (master and slave)
|
# Check mysql tz import (master and slave)
|
||||||
TZ_CHECK=$(mysql --socket=/var/run/mysqld/mysqld.sock -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "SELECT CONVERT_TZ('2019-11-02 23:33:00','Europe/Berlin','UTC') AS time;" -BN 2> /dev/null)
|
TZ_CHECK=$(mysql --socket=/var/run/mysqld/mysqld.sock -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "SELECT CONVERT_TZ('2019-11-02 23:33:00','Europe/Berlin','UTC') AS time;" -BN 2> /dev/null)
|
||||||
if [[ -z ${TZ_CHECK} ]] || [[ "${TZ_CHECK}" == "NULL" ]]; then
|
if [[ -z ${TZ_CHECK} ]] || [[ "${TZ_CHECK}" == "NULL" ]]; then
|
||||||
SQL_FULL_TZINFO_IMPORT_RETURN=$(curl --silent --insecure -XPOST https://dockerapi/containers/${CONTAINER_ID}/exec -d '{"cmd":"system", "task":"mysql_tzinfo_to_sql"}' --silent -H 'Content-type: application/json')
|
SQL_FULL_TZINFO_IMPORT_RETURN=$(curl --silent --insecure -XPOST https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${CONTAINER_ID}/exec -d '{"cmd":"system", "task":"mysql_tzinfo_to_sql"}' --silent -H 'Content-type: application/json')
|
||||||
echo "MySQL mysql_tzinfo_to_sql - debug output:"
|
echo "MySQL mysql_tzinfo_to_sql - debug output:"
|
||||||
echo ${SQL_FULL_TZINFO_IMPORT_RETURN}
|
echo ${SQL_FULL_TZINFO_IMPORT_RETURN}
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
FROM debian:bookworm-slim
|
FROM debian:bookworm-slim
|
||||||
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
|
||||||
|
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
|
||||||
|
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
ENV LC_ALL C
|
ENV LC_ALL C
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
FROM debian:bullseye-slim
|
FROM debian:bookworm-slim
|
||||||
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
|
||||||
|
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
ARG RSPAMD_VER=rspamd_3.7.5-2~8c86c1676
|
ARG RSPAMD_VER=rspamd_3.9.1-1~82f43560f
|
||||||
ARG CODENAME=bullseye
|
ARG CODENAME=bookworm
|
||||||
ENV LC_ALL C
|
ENV LC_ALL=C
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
tzdata \
|
tzdata \
|
||||||
@@ -12,11 +12,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
gnupg2 \
|
gnupg2 \
|
||||||
apt-transport-https \
|
apt-transport-https \
|
||||||
dnsutils \
|
dnsutils \
|
||||||
netcat \
|
netcat-traditional \
|
||||||
wget \
|
wget \
|
||||||
redis-tools \
|
redis-tools \
|
||||||
procps \
|
procps \
|
||||||
nano \
|
nano \
|
||||||
|
lua-cjson \
|
||||||
&& arch=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) \
|
&& arch=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) \
|
||||||
&& wget -P /tmp https://rspamd.com/apt-stable/pool/main/r/rspamd/${RSPAMD_VER}~${CODENAME}_${arch}.deb\
|
&& wget -P /tmp https://rspamd.com/apt-stable/pool/main/r/rspamd/${RSPAMD_VER}~${CODENAME}_${arch}.deb\
|
||||||
&& apt install -y /tmp/${RSPAMD_VER}~${CODENAME}_${arch}.deb \
|
&& apt install -y /tmp/${RSPAMD_VER}~${CODENAME}_${arch}.deb \
|
||||||
|
|||||||
@@ -124,4 +124,190 @@ for file in /hooks/*; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# If DQS KEY is set in mailcow.conf add Spamhaus DQS RBLs
|
||||||
|
if [[ ! -z ${SPAMHAUS_DQS_KEY} ]]; then
|
||||||
|
cat <<EOF > /etc/rspamd/custom/dqs-rbl.conf
|
||||||
|
# Autogenerated by mailcow. DO NOT TOUCH!
|
||||||
|
spamhaus {
|
||||||
|
rbl = "${SPAMHAUS_DQS_KEY}.zen.dq.spamhaus.net";
|
||||||
|
from = false;
|
||||||
|
}
|
||||||
|
spamhaus_from {
|
||||||
|
from = true;
|
||||||
|
received = false;
|
||||||
|
rbl = "${SPAMHAUS_DQS_KEY}.zen.dq.spamhaus.net";
|
||||||
|
returncodes {
|
||||||
|
SPAMHAUS_ZEN = [ "127.0.0.2", "127.0.0.3", "127.0.0.4", "127.0.0.5", "127.0.0.6", "127.0.0.7", "127.0.0.9", "127.0.0.10", "127.0.0.11" ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spamhaus_authbl_received {
|
||||||
|
# Check if the sender client is listed in AuthBL (AuthBL is *not* part of ZEN)
|
||||||
|
rbl = "${SPAMHAUS_DQS_KEY}.authbl.dq.spamhaus.net";
|
||||||
|
from = false;
|
||||||
|
received = true;
|
||||||
|
ipv6 = true;
|
||||||
|
returncodes {
|
||||||
|
SH_AUTHBL_RECEIVED = "127.0.0.20"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spamhaus_dbl {
|
||||||
|
# Add checks on the HELO string
|
||||||
|
rbl = "${SPAMHAUS_DQS_KEY}.dbl.dq.spamhaus.net";
|
||||||
|
helo = true;
|
||||||
|
rdns = true;
|
||||||
|
dkim = true;
|
||||||
|
disable_monitoring = true;
|
||||||
|
returncodes {
|
||||||
|
RBL_DBL_SPAM = "127.0.1.2";
|
||||||
|
RBL_DBL_PHISH = "127.0.1.4";
|
||||||
|
RBL_DBL_MALWARE = "127.0.1.5";
|
||||||
|
RBL_DBL_BOTNET = "127.0.1.6";
|
||||||
|
RBL_DBL_ABUSED_SPAM = "127.0.1.102";
|
||||||
|
RBL_DBL_ABUSED_PHISH = "127.0.1.104";
|
||||||
|
RBL_DBL_ABUSED_MALWARE = "127.0.1.105";
|
||||||
|
RBL_DBL_ABUSED_BOTNET = "127.0.1.106";
|
||||||
|
RBL_DBL_DONT_QUERY_IPS = "127.0.1.255";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spamhaus_dbl_fullurls {
|
||||||
|
ignore_defaults = true;
|
||||||
|
no_ip = true;
|
||||||
|
rbl = "${SPAMHAUS_DQS_KEY}.dbl.dq.spamhaus.net";
|
||||||
|
selector = 'urls:get_host'
|
||||||
|
disable_monitoring = true;
|
||||||
|
returncodes {
|
||||||
|
DBLABUSED_SPAM_FULLURLS = "127.0.1.102";
|
||||||
|
DBLABUSED_PHISH_FULLURLS = "127.0.1.104";
|
||||||
|
DBLABUSED_MALWARE_FULLURLS = "127.0.1.105";
|
||||||
|
DBLABUSED_BOTNET_FULLURLS = "127.0.1.106";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spamhaus_zrd {
|
||||||
|
# Add checks on the HELO string also for DQS
|
||||||
|
rbl = "${SPAMHAUS_DQS_KEY}.zrd.dq.spamhaus.net";
|
||||||
|
helo = true;
|
||||||
|
rdns = true;
|
||||||
|
dkim = true;
|
||||||
|
disable_monitoring = true;
|
||||||
|
returncodes {
|
||||||
|
RBL_ZRD_VERY_FRESH_DOMAIN = ["127.0.2.2", "127.0.2.3", "127.0.2.4"];
|
||||||
|
RBL_ZRD_FRESH_DOMAIN = [
|
||||||
|
"127.0.2.5", "127.0.2.6", "127.0.2.7", "127.0.2.8", "127.0.2.9", "127.0.2.10", "127.0.2.11", "127.0.2.12", "127.0.2.13", "127.0.2.14", "127.0.2.15", "127.0.2.16", "127.0.2.17", "127.0.2.18", "127.0.2.19", "127.0.2.20", "127.0.2.21", "127.0.2.22", "127.0.2.23", "127.0.2.24"
|
||||||
|
];
|
||||||
|
RBL_ZRD_DONT_QUERY_IPS = "127.0.2.255";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"SPAMHAUS_ZEN_URIBL" {
|
||||||
|
enabled = true;
|
||||||
|
rbl = "${SPAMHAUS_DQS_KEY}.zen.dq.spamhaus.net";
|
||||||
|
resolve_ip = true;
|
||||||
|
checks = ['urls'];
|
||||||
|
replyto = true;
|
||||||
|
emails = true;
|
||||||
|
ipv4 = true;
|
||||||
|
ipv6 = true;
|
||||||
|
emails_domainonly = true;
|
||||||
|
returncodes {
|
||||||
|
URIBL_SBL = "127.0.0.2";
|
||||||
|
URIBL_SBL_CSS = "127.0.0.3";
|
||||||
|
URIBL_XBL = ["127.0.0.4", "127.0.0.5", "127.0.0.6", "127.0.0.7"];
|
||||||
|
URIBL_PBL = ["127.0.0.10", "127.0.0.11"];
|
||||||
|
URIBL_DROP = "127.0.0.9";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SH_EMAIL_DBL {
|
||||||
|
ignore_defaults = true;
|
||||||
|
replyto = true;
|
||||||
|
emails_domainonly = true;
|
||||||
|
disable_monitoring = true;
|
||||||
|
rbl = "${SPAMHAUS_DQS_KEY}.dbl.dq.spamhaus.net";
|
||||||
|
returncodes = {
|
||||||
|
SH_EMAIL_DBL = [
|
||||||
|
"127.0.1.2",
|
||||||
|
"127.0.1.4",
|
||||||
|
"127.0.1.5",
|
||||||
|
"127.0.1.6"
|
||||||
|
];
|
||||||
|
SH_EMAIL_DBL_ABUSED = [
|
||||||
|
"127.0.1.102",
|
||||||
|
"127.0.1.104",
|
||||||
|
"127.0.1.105",
|
||||||
|
"127.0.1.106"
|
||||||
|
];
|
||||||
|
SH_EMAIL_DBL_DONT_QUERY_IPS = [ "127.0.1.255" ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SH_EMAIL_ZRD {
|
||||||
|
ignore_defaults = true;
|
||||||
|
replyto = true;
|
||||||
|
emails_domainonly = true;
|
||||||
|
disable_monitoring = true;
|
||||||
|
rbl = "${SPAMHAUS_DQS_KEY}.zrd.dq.spamhaus.net";
|
||||||
|
returncodes = {
|
||||||
|
SH_EMAIL_ZRD_VERY_FRESH_DOMAIN = ["127.0.2.2", "127.0.2.3", "127.0.2.4"];
|
||||||
|
SH_EMAIL_ZRD_FRESH_DOMAIN = [
|
||||||
|
"127.0.2.5", "127.0.2.6", "127.0.2.7", "127.0.2.8", "127.0.2.9", "127.0.2.10", "127.0.2.11", "127.0.2.12", "127.0.2.13", "127.0.2.14", "127.0.2.15", "127.0.2.16", "127.0.2.17", "127.0.2.18", "127.0.2.19", "127.0.2.20", "127.0.2.21", "127.0.2.22", "127.0.2.23", "127.0.2.24"
|
||||||
|
];
|
||||||
|
SH_EMAIL_ZRD_DONT_QUERY_IPS = [ "127.0.2.255" ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"DBL" {
|
||||||
|
# override the defaults for DBL defined in modules.d/rbl.conf
|
||||||
|
rbl = "${SPAMHAUS_DQS_KEY}.dbl.dq.spamhaus.net";
|
||||||
|
disable_monitoring = true;
|
||||||
|
}
|
||||||
|
"ZRD" {
|
||||||
|
ignore_defaults = true;
|
||||||
|
rbl = "${SPAMHAUS_DQS_KEY}.zrd.dq.spamhaus.net";
|
||||||
|
no_ip = true;
|
||||||
|
dkim = true;
|
||||||
|
emails = true;
|
||||||
|
emails_domainonly = true;
|
||||||
|
urls = true;
|
||||||
|
returncodes = {
|
||||||
|
ZRD_VERY_FRESH_DOMAIN = ["127.0.2.2", "127.0.2.3", "127.0.2.4"];
|
||||||
|
ZRD_FRESH_DOMAIN = ["127.0.2.5", "127.0.2.6", "127.0.2.7", "127.0.2.8", "127.0.2.9", "127.0.2.10", "127.0.2.11", "127.0.2.12", "127.0.2.13", "127.0.2.14", "127.0.2.15", "127.0.2.16", "127.0.2.17", "127.0.2.18", "127.0.2.19", "127.0.2.20", "127.0.2.21", "127.0.2.22", "127.0.2.23", "127.0.2.24"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spamhaus_sbl_url {
|
||||||
|
ignore_defaults = true
|
||||||
|
rbl = "${SPAMHAUS_DQS_KEY}.sbl.dq.spamhaus.net";
|
||||||
|
checks = ['urls'];
|
||||||
|
disable_monitoring = true;
|
||||||
|
returncodes {
|
||||||
|
SPAMHAUS_SBL_URL = "127.0.0.2";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SH_HBL_EMAIL {
|
||||||
|
ignore_defaults = true;
|
||||||
|
rbl = "_email.${SPAMHAUS_DQS_KEY}.hbl.dq.spamhaus.net";
|
||||||
|
emails_domainonly = false;
|
||||||
|
selector = "from('smtp').lower;from('mime').lower";
|
||||||
|
ignore_whitelist = true;
|
||||||
|
checks = ['emails', 'replyto'];
|
||||||
|
hash = "sha1";
|
||||||
|
returncodes = {
|
||||||
|
SH_HBL_EMAIL = [
|
||||||
|
"127.0.3.2"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spamhaus_dqs_hbl {
|
||||||
|
symbol = "HBL_FILE_UNKNOWN";
|
||||||
|
rbl = "_file.${SPAMHAUS_DQS_KEY}.hbl.dq.spamhaus.net.";
|
||||||
|
selector = "attachments('rbase32', 'sha256')";
|
||||||
|
ignore_whitelist = true;
|
||||||
|
ignore_defaults = true;
|
||||||
|
returncodes {
|
||||||
|
SH_HBL_FILE_MALICIOUS = "127.0.3.10";
|
||||||
|
SH_HBL_FILE_SUSPICIOUS = "127.0.3.15";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
rm -rf /etc/rspamd/custom/dqs-rbl.conf
|
||||||
|
fi
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
FROM debian:bullseye-slim
|
FROM debian:bullseye-slim
|
||||||
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
|
||||||
|
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
|
||||||
|
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
ARG DEBIAN_VERSION=bullseye
|
ARG DEBIAN_VERSION=bullseye
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
FROM alpine:3.20
|
FROM alpine:3.20
|
||||||
|
|
||||||
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
|
||||||
|
|
||||||
RUN apk add --update --no-cache \
|
RUN apk add --update --no-cache \
|
||||||
curl \
|
curl \
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
FROM alpine:3.20
|
FROM alpine:3.20
|
||||||
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
|
||||||
|
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
RUN apk add --update \
|
RUN apk add --update \
|
||||||
|
|||||||
@@ -191,12 +191,12 @@ get_container_ip() {
|
|||||||
else
|
else
|
||||||
sleep 0.5
|
sleep 0.5
|
||||||
# get long container id for exact match
|
# get long container id for exact match
|
||||||
CONTAINER_ID=($(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring == \"${1}\") | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id"))
|
CONTAINER_ID=($(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring == \"${1}\") | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id"))
|
||||||
# returned id can have multiple elements (if scaled), shuffle for random test
|
# returned id can have multiple elements (if scaled), shuffle for random test
|
||||||
CONTAINER_ID=($(printf "%s\n" "${CONTAINER_ID[@]}" | shuf))
|
CONTAINER_ID=($(printf "%s\n" "${CONTAINER_ID[@]}" | shuf))
|
||||||
if [[ ! -z ${CONTAINER_ID} ]]; then
|
if [[ ! -z ${CONTAINER_ID} ]]; then
|
||||||
for matched_container in "${CONTAINER_ID[@]}"; do
|
for matched_container in "${CONTAINER_ID[@]}"; do
|
||||||
CONTAINER_IPS=($(curl --silent --insecure https://dockerapi/containers/${matched_container}/json | jq -r '.NetworkSettings.Networks[].IPAddress'))
|
CONTAINER_IPS=($(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${matched_container}/json | jq -r '.NetworkSettings.Networks[].IPAddress'))
|
||||||
for ip_match in "${CONTAINER_IPS[@]}"; do
|
for ip_match in "${CONTAINER_IPS[@]}"; do
|
||||||
# grep will do nothing if one of these vars is empty
|
# grep will do nothing if one of these vars is empty
|
||||||
[[ -z ${ip_match} ]] && continue
|
[[ -z ${ip_match} ]] && continue
|
||||||
@@ -716,7 +716,7 @@ rspamd_checks() {
|
|||||||
From: watchdog@localhost
|
From: watchdog@localhost
|
||||||
|
|
||||||
Empty
|
Empty
|
||||||
' | usr/bin/curl --max-time 10 -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/scan | jq -rc .default.required_score | sed 's/\..*//' )
|
' | usr/bin/curl --max-time 10 -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd.${COMPOSE_PROJECT_NAME}_mailcow-network/scan | jq -rc .default.required_score | sed 's/\..*//' )
|
||||||
if [[ ${SCORE} -ne 9999 ]]; then
|
if [[ ${SCORE} -ne 9999 ]]; then
|
||||||
echo "Rspamd settings check failed, score returned: ${SCORE}" 2>> /tmp/rspamd-mailcow 1>&2
|
echo "Rspamd settings check failed, score returned: ${SCORE}" 2>> /tmp/rspamd-mailcow 1>&2
|
||||||
err_count=$(( ${err_count} + 1))
|
err_count=$(( ${err_count} + 1))
|
||||||
@@ -1095,12 +1095,12 @@ while true; do
|
|||||||
elif [[ ${com_pipe_answer} =~ .+-mailcow ]]; then
|
elif [[ ${com_pipe_answer} =~ .+-mailcow ]]; then
|
||||||
kill -STOP ${BACKGROUND_TASKS[*]}
|
kill -STOP ${BACKGROUND_TASKS[*]}
|
||||||
sleep 10
|
sleep 10
|
||||||
CONTAINER_ID=$(curl --silent --insecure https://dockerapi/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"${com_pipe_answer}\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id")
|
CONTAINER_ID=$(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/json | jq -r ".[] | {name: .Config.Labels[\"com.docker.compose.service\"], project: .Config.Labels[\"com.docker.compose.project\"], id: .Id}" | jq -rc "select( .name | tostring | contains(\"${com_pipe_answer}\")) | select( .project | tostring | contains(\"${COMPOSE_PROJECT_NAME,,}\")) | .id")
|
||||||
if [[ ! -z ${CONTAINER_ID} ]]; then
|
if [[ ! -z ${CONTAINER_ID} ]]; then
|
||||||
if [[ "${com_pipe_answer}" == "php-fpm-mailcow" ]]; then
|
if [[ "${com_pipe_answer}" == "php-fpm-mailcow" ]]; then
|
||||||
HAS_INITDB=$(curl --silent --insecure -XPOST https://dockerapi/containers/${CONTAINER_ID}/top | jq '.msg.Processes[] | contains(["php -c /usr/local/etc/php -f /web/inc/init_db.inc.php"])' | grep true)
|
HAS_INITDB=$(curl --silent --insecure -XPOST https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${CONTAINER_ID}/top | jq '.msg.Processes[] | contains(["php -c /usr/local/etc/php -f /web/inc/init_db.inc.php"])' | grep true)
|
||||||
fi
|
fi
|
||||||
S_RUNNING=$(($(date +%s) - $(curl --silent --insecure https://dockerapi/containers/${CONTAINER_ID}/json | jq .State.StartedAt | xargs -n1 date +%s -d)))
|
S_RUNNING=$(($(date +%s) - $(curl --silent --insecure https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${CONTAINER_ID}/json | jq .State.StartedAt | xargs -n1 date +%s -d)))
|
||||||
if [ ${S_RUNNING} -lt 360 ]; then
|
if [ ${S_RUNNING} -lt 360 ]; then
|
||||||
log_msg "Container is running for less than 360 seconds, skipping action..."
|
log_msg "Container is running for less than 360 seconds, skipping action..."
|
||||||
elif [[ ! -z ${HAS_INITDB} ]]; then
|
elif [[ ! -z ${HAS_INITDB} ]]; then
|
||||||
@@ -1108,7 +1108,7 @@ while true; do
|
|||||||
sleep 60
|
sleep 60
|
||||||
else
|
else
|
||||||
log_msg "Sending restart command to ${CONTAINER_ID}..."
|
log_msg "Sending restart command to ${CONTAINER_ID}..."
|
||||||
curl --silent --insecure -XPOST https://dockerapi/containers/${CONTAINER_ID}/restart
|
curl --silent --insecure -XPOST https://dockerapi.${COMPOSE_PROJECT_NAME}_mailcow-network/containers/${CONTAINER_ID}/restart
|
||||||
notify_error "${com_pipe_answer}"
|
notify_error "${com_pipe_answer}"
|
||||||
log_msg "Wait for restarted container to settle and continue watching..."
|
log_msg "Wait for restarted container to settle and continue watching..."
|
||||||
sleep 35
|
sleep 35
|
||||||
|
|||||||
@@ -289,5 +289,20 @@ namespace inbox {
|
|||||||
mailbox "Kladde" {
|
mailbox "Kladde" {
|
||||||
special_use = \Drafts
|
special_use = \Drafts
|
||||||
}
|
}
|
||||||
|
mailbox "Πρόχειρα" {
|
||||||
|
special_use = \Drafts
|
||||||
|
}
|
||||||
|
mailbox "Απεσταλμένα" {
|
||||||
|
special_use = \Sent
|
||||||
|
}
|
||||||
|
mailbox "Κάδος απορριμάτων" {
|
||||||
|
special_use = \Trash
|
||||||
|
}
|
||||||
|
mailbox "Ανεπιθύμητα" {
|
||||||
|
special_use = \Junk
|
||||||
|
}
|
||||||
|
mailbox "Αρχειοθετημένα" {
|
||||||
|
special_use = \Archive
|
||||||
|
}
|
||||||
prefix =
|
prefix =
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ rbls {
|
|||||||
interserver_ip {
|
interserver_ip {
|
||||||
symbol = "RBL_INTERSERVER_IP";
|
symbol = "RBL_INTERSERVER_IP";
|
||||||
rbl = "rbl.interserver.net";
|
rbl = "rbl.interserver.net";
|
||||||
|
from = true;
|
||||||
ipv6 = false;
|
ipv6 = false;
|
||||||
returncodes {
|
returncodes {
|
||||||
RBL_INTERSERVER_BAD_IP = "127.0.0.2";
|
RBL_INTERSERVER_BAD_IP = "127.0.0.2";
|
||||||
@@ -19,4 +20,7 @@ rbls {
|
|||||||
RBL_INTERSERVER_BAD_URI = "127.0.0.2";
|
RBL_INTERSERVER_BAD_URI = "127.0.0.2";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
.include(try=true,override=true,priority=5) "$LOCAL_CONFDIR/custom/dqs-rbl.conf"
|
||||||
|
|
||||||
|
}
|
||||||
@@ -17,4 +17,261 @@ symbols = {
|
|||||||
score = 4.0;
|
score = 4.0;
|
||||||
description = "Listed on Interserver RBL";
|
description = "Listed on Interserver RBL";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"SPAMHAUS_ZEN" {
|
||||||
|
weight = 7.0;
|
||||||
|
}
|
||||||
|
"SH_AUTHBL_RECEIVED" {
|
||||||
|
weight = 4.0;
|
||||||
|
}
|
||||||
|
"RBL_DBL_SPAM" {
|
||||||
|
weight = 7.0;
|
||||||
|
}
|
||||||
|
"RBL_DBL_PHISH" {
|
||||||
|
weight = 7.0;
|
||||||
|
}
|
||||||
|
"RBL_DBL_MALWARE" {
|
||||||
|
weight = 7.0;
|
||||||
|
}
|
||||||
|
"RBL_DBL_BOTNET" {
|
||||||
|
weight = 7.0;
|
||||||
|
}
|
||||||
|
"RBL_DBL_ABUSED_SPAM" {
|
||||||
|
weight = 3.0;
|
||||||
|
}
|
||||||
|
"RBL_DBL_ABUSED_PHISH" {
|
||||||
|
weight = 3.0;
|
||||||
|
}
|
||||||
|
"RBL_DBL_ABUSED_MALWARE" {
|
||||||
|
weight = 3.0;
|
||||||
|
}
|
||||||
|
"RBL_DBL_ABUSED_BOTNET" {
|
||||||
|
weight = 3.0;
|
||||||
|
}
|
||||||
|
"RBL_ZRD_VERY_FRESH_DOMAIN" {
|
||||||
|
weight = 7.0;
|
||||||
|
}
|
||||||
|
"RBL_ZRD_FRESH_DOMAIN" {
|
||||||
|
weight = 4.0;
|
||||||
|
}
|
||||||
|
"ZRD_VERY_FRESH_DOMAIN" {
|
||||||
|
weight = 7.0;
|
||||||
|
}
|
||||||
|
"ZRD_FRESH_DOMAIN" {
|
||||||
|
weight = 4.0;
|
||||||
|
}
|
||||||
|
"SH_EMAIL_DBL" {
|
||||||
|
weight = 7.0;
|
||||||
|
}
|
||||||
|
"SH_EMAIL_DBL_ABUSED" {
|
||||||
|
weight = 7.0;
|
||||||
|
}
|
||||||
|
"SH_EMAIL_ZRD_VERY_FRESH_DOMAIN" {
|
||||||
|
weight = 7.0;
|
||||||
|
}
|
||||||
|
"SH_EMAIL_ZRD_FRESH_DOMAIN" {
|
||||||
|
weight = 4.0;
|
||||||
|
}
|
||||||
|
"RBL_DBL_DONT_QUERY_IPS" {
|
||||||
|
weight = 0.0;
|
||||||
|
}
|
||||||
|
"RBL_ZRD_DONT_QUERY_IPS" {
|
||||||
|
weight = 0.0;
|
||||||
|
}
|
||||||
|
"SH_EMAIL_ZRD_DONT_QUERY_IPS" {
|
||||||
|
weight = 0.0;
|
||||||
|
}
|
||||||
|
"SH_EMAIL_DBL_DONT_QUERY_IPS" {
|
||||||
|
weight = 0.0;
|
||||||
|
}
|
||||||
|
"DBL" {
|
||||||
|
weight = 0.0;
|
||||||
|
description = "DBL unknown result";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBL_SPAM" {
|
||||||
|
weight = 7;
|
||||||
|
description = "DBL uribl spam";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBL_PHISH" {
|
||||||
|
weight = 7;
|
||||||
|
description = "DBL uribl phishing";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBL_MALWARE" {
|
||||||
|
weight = 7;
|
||||||
|
description = "DBL uribl malware";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBL_BOTNET" {
|
||||||
|
weight = 7;
|
||||||
|
description = "DBL uribl botnet C&C domain";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
"DBLABUSED_SPAM_FULLURLS" {
|
||||||
|
weight = 5.5;
|
||||||
|
description = "DBL uribl abused legit spam";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBLABUSED_PHISH_FULLURLS" {
|
||||||
|
weight = 5.5;
|
||||||
|
description = "DBL uribl abused legit phish";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBLABUSED_MALWARE_FULLURLS" {
|
||||||
|
weight = 5.5;
|
||||||
|
description = "DBL uribl abused legit malware";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBLABUSED_BOTNET_FULLURLS" {
|
||||||
|
weight = 5.5;
|
||||||
|
description = "DBL uribl abused legit botnet";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
|
||||||
|
"DBL_ABUSE" {
|
||||||
|
weight = 5.5;
|
||||||
|
description = "DBL uribl abused legit spam";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBL_ABUSE_REDIR" {
|
||||||
|
weight = 1.5;
|
||||||
|
description = "DBL uribl abused spammed redirector domain";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBL_ABUSE_PHISH" {
|
||||||
|
weight = 5.5;
|
||||||
|
description = "DBL uribl abused legit phish";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBL_ABUSE_MALWARE" {
|
||||||
|
weight = 5.5;
|
||||||
|
description = "DBL uribl abused legit malware";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBL_ABUSE_BOTNET" {
|
||||||
|
weight = 5.5;
|
||||||
|
description = "DBL uribl abused legit botnet C&C";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBL_PROHIBIT" {
|
||||||
|
weight = 0.0;
|
||||||
|
description = "DBL uribl IP queries prohibited!";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBL_BLOCKED_OPENRESOLVER" {
|
||||||
|
weight = 0.0;
|
||||||
|
description = "You are querying Spamhaus from an open resolver, please see https://www.spamhaus.org/returnc/pub/";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"DBL_BLOCKED" {
|
||||||
|
weight = 0.0;
|
||||||
|
description = "You are exceeding the query limit, please see https://www.spamhaus.org/returnc/vol/";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"SPAMHAUS_ZEN_URIBL" {
|
||||||
|
weight = 0.0;
|
||||||
|
description = "Spamhaus ZEN URIBL: Filtered result";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"URIBL_SBL" {
|
||||||
|
weight = 6.5;
|
||||||
|
description = "A domain in the message body resolves to an IP listed in Spamhaus SBL";
|
||||||
|
one_shot = true;
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"URIBL_SBL_CSS" {
|
||||||
|
weight = 6.5;
|
||||||
|
description = "A domain in the message body resolves to an IP listed in Spamhaus SBL CSS";
|
||||||
|
one_shot = true;
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"URIBL_PBL" {
|
||||||
|
weight = 0.01;
|
||||||
|
description = "A domain in the message body resolves to an IP listed in Spamhaus PBL";
|
||||||
|
one_shot = true;
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"URIBL_DROP" {
|
||||||
|
weight = 6.5;
|
||||||
|
description = "A domain in the message body resolves to an IP listed in Spamhaus DROP";
|
||||||
|
one_shot = true;
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"URIBL_XBL" {
|
||||||
|
weight = 5.0;
|
||||||
|
description = "A domain in the message body resolves to an IP listed in Spamhaus XBL";
|
||||||
|
one_shot = true;
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
"SPAMHAUS_SBL_URL" {
|
||||||
|
weight = 6.5;
|
||||||
|
description = "A numeric URL in the message body is listed in Spamhaus SBL";
|
||||||
|
one_shot = true;
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
|
||||||
|
"SH_HBL_EMAIL" {
|
||||||
|
weight = 7;
|
||||||
|
description = "Email listed in HBL";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
|
||||||
|
"SH_HBL_FILE_MALICIOUS" {
|
||||||
|
weight = 7;
|
||||||
|
description = "An attachment hash is listed in Spamhaus HBL as malicious";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
|
||||||
|
"SH_HBL_FILE_SUSPICIOUS" {
|
||||||
|
weight = 5;
|
||||||
|
description = "An attachment hash is listed in Spamhaus HBL as suspicious";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
|
||||||
|
"RBL_SPAMHAUS_CW_BTC" {
|
||||||
|
score = 7;
|
||||||
|
description = "Bitcoin found in Spamhaus cryptowallet list";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
|
||||||
|
"RBL_SPAMHAUS_CW_ETH" {
|
||||||
|
score = 7;
|
||||||
|
description = "Ethereum found in Spamhaus cryptowallet list";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
|
||||||
|
"RBL_SPAMHAUS_CW_BCH" {
|
||||||
|
score = 7;
|
||||||
|
description = "Bitcoinhash found in Spamhaus cryptowallet list";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
|
||||||
|
"RBL_SPAMHAUS_CW_XMR" {
|
||||||
|
score = 7;
|
||||||
|
description = "Monero found in Spamhaus cryptowallet list";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
|
||||||
|
"RBL_SPAMHAUS_CW_LTC" {
|
||||||
|
score = 7;
|
||||||
|
description = "Litecoin found in Spamhaus cryptowallet list";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
|
||||||
|
"RBL_SPAMHAUS_CW_XRP" {
|
||||||
|
score = 7;
|
||||||
|
description = "Ripple found in Spamhaus cryptowallet list";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
|
||||||
|
"RBL_SPAMHAUS_HBL_URL" {
|
||||||
|
score = 7;
|
||||||
|
description = "URL found in spamhaus HBL blocklist";
|
||||||
|
groups = ["spamhaus"];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ header('Content-Type: application/xml');
|
|||||||
<username>%EMAILADDRESS%</username>
|
<username>%EMAILADDRESS%</username>
|
||||||
<authentication>password-cleartext</authentication>
|
<authentication>password-cleartext</authentication>
|
||||||
</incomingServer>
|
</incomingServer>
|
||||||
|
<?php
|
||||||
|
$records = dns_get_record('_imap._tcp.' . $domain, DNS_SRV); // check if IMAP is announced as "not provided" via SRV record
|
||||||
|
if (count($records) == 0 || $records[0]['target'] != '') { ?>
|
||||||
<incomingServer type="imap">
|
<incomingServer type="imap">
|
||||||
<hostname><?=$autodiscover_config['imap']['server']; ?></hostname>
|
<hostname><?=$autodiscover_config['imap']['server']; ?></hostname>
|
||||||
<port><?=$autodiscover_config['imap']['tlsport']; ?></port>
|
<port><?=$autodiscover_config['imap']['tlsport']; ?></port>
|
||||||
@@ -46,6 +49,7 @@ header('Content-Type: application/xml');
|
|||||||
<username>%EMAILADDRESS%</username>
|
<username>%EMAILADDRESS%</username>
|
||||||
<authentication>password-cleartext</authentication>
|
<authentication>password-cleartext</authentication>
|
||||||
</incomingServer>
|
</incomingServer>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$records = dns_get_record('_pop3s._tcp.' . $domain, DNS_SRV); // check if POP3 is announced as "not provided" via SRV record
|
$records = dns_get_record('_pop3s._tcp.' . $domain, DNS_SRV); // check if POP3 is announced as "not provided" via SRV record
|
||||||
@@ -77,6 +81,9 @@ if (count($records) == 0 || $records[0]['target'] != '') { ?>
|
|||||||
<username>%EMAILADDRESS%</username>
|
<username>%EMAILADDRESS%</username>
|
||||||
<authentication>password-cleartext</authentication>
|
<authentication>password-cleartext</authentication>
|
||||||
</outgoingServer>
|
</outgoingServer>
|
||||||
|
<?php
|
||||||
|
$records = dns_get_record('_smtp._tcp.' . $domain, DNS_SRV); // check if SMTP is announced as "not provided" via SRV record
|
||||||
|
if (count($records) == 0 || $records[0]['target'] != '') { ?>
|
||||||
<outgoingServer type="smtp">
|
<outgoingServer type="smtp">
|
||||||
<hostname><?=$autodiscover_config['smtp']['server']; ?></hostname>
|
<hostname><?=$autodiscover_config['smtp']['server']; ?></hostname>
|
||||||
<port><?=$autodiscover_config['smtp']['tlsport']; ?></port>
|
<port><?=$autodiscover_config['smtp']['tlsport']; ?></port>
|
||||||
@@ -84,6 +91,7 @@ if (count($records) == 0 || $records[0]['target'] != '') { ?>
|
|||||||
<username>%EMAILADDRESS%</username>
|
<username>%EMAILADDRESS%</username>
|
||||||
<authentication>password-cleartext</authentication>
|
<authentication>password-cleartext</authentication>
|
||||||
</outgoingServer>
|
</outgoingServer>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
<enable visiturl="https://<?=$mailcow_hostname; ?><?php if ($port != 443) echo ':'.$port; ?>/admin.php">
|
<enable visiturl="https://<?=$mailcow_hostname; ?><?php if ($port != 443) echo ':'.$port; ?>/admin.php">
|
||||||
<instruction>If you didn't change the password given to you by the administrator or if you didn't change it in a long time, please consider doing that now.</instruction>
|
<instruction>If you didn't change the password given to you by the administrator or if you didn't change it in a long time, please consider doing that now.</instruction>
|
||||||
|
|||||||
33
data/web/inc/lib/sieve/extensions/enotify.xml
Normal file
33
data/web/inc/lib/sieve/extensions/enotify.xml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version='1.0' standalone='yes'?>
|
||||||
|
|
||||||
|
<extension name="enotify">
|
||||||
|
<command name="notify">
|
||||||
|
<parameter type="tag" name="from" occurrence="optional">
|
||||||
|
<parameter type="string" name="from-address" />
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
<parameter type="tag" name="importance" regex="(1|2|3)" occurrence="optional" />
|
||||||
|
|
||||||
|
<parameter type="tag" name="options" occurrence="optional">
|
||||||
|
<parameter type="stringlist" name="option-strings" />
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
<parameter type="tag" name="message" occurrence="optional">
|
||||||
|
<parameter type="string" name="message-text" />
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
<parameter type="string" name="method" />
|
||||||
|
</command>
|
||||||
|
|
||||||
|
<test name="valid_notify_method">
|
||||||
|
<parameter type="stringlist" name="notification-uris" />
|
||||||
|
</test>
|
||||||
|
|
||||||
|
<test name="notify_method_capability">
|
||||||
|
<parameter type="string" name="notification-uri" />
|
||||||
|
<parameter type="string" name="notification-capability" />
|
||||||
|
<parameter type="stringlist" name="key-list" />
|
||||||
|
</test>
|
||||||
|
|
||||||
|
<modifier name="encodeurl" />
|
||||||
|
</extension>
|
||||||
58
data/web/inc/lib/sieve/extensions/mime.xml
Normal file
58
data/web/inc/lib/sieve/extensions/mime.xml
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<?xml version='1.0' standalone='yes'?>
|
||||||
|
|
||||||
|
<extension name="mime">
|
||||||
|
<command name="foreverypart">
|
||||||
|
<parameter type="string" name="name" occurrence="optional" />
|
||||||
|
<block />
|
||||||
|
</command>
|
||||||
|
|
||||||
|
<command name="break">
|
||||||
|
<parameter type="string" name="name" occurrence="optional" />
|
||||||
|
</command>
|
||||||
|
|
||||||
|
<tagged-argument extends="(header|address|exists)">
|
||||||
|
<parameter type="tag" name="mime" regex="mime" occurrence="optional" />
|
||||||
|
</tagged-argument>
|
||||||
|
<tagged-argument extends="(header|address|exists)">
|
||||||
|
<parameter type="tag" name="anychild" regex="anychild" occurrence="optional" />
|
||||||
|
</tagged-argument>
|
||||||
|
<tagged-argument extends="(header)">
|
||||||
|
<parameter type="tag" name="type" occurrence="optional" />
|
||||||
|
</tagged-argument>
|
||||||
|
<tagged-argument extends="(header)">
|
||||||
|
<parameter type="tag" name="subtype" occurrence="optional" />
|
||||||
|
</tagged-argument>
|
||||||
|
<tagged-argument extends="(header)">
|
||||||
|
<parameter type="tag" name="contenttype" occurrence="optional" />
|
||||||
|
</tagged-argument>
|
||||||
|
<tagged-argument extends="(header)">
|
||||||
|
<parameter type="tag" name="param" regex="param" occurrence="optional">
|
||||||
|
<parameter type="stringlist" name="param-list" />
|
||||||
|
</parameter>
|
||||||
|
</tagged-argument>
|
||||||
|
<tagged-argument extends="(header|address|exists)">
|
||||||
|
<parameter type="stringlist" name="header-names" />
|
||||||
|
</tagged-argument>
|
||||||
|
<tagged-argument extends="(header)">
|
||||||
|
<parameter type="stringlist" name="key-list" />
|
||||||
|
</tagged-argument>
|
||||||
|
|
||||||
|
<action name="replace">
|
||||||
|
<parameter type="tag" name="mime" regex="mime" occurrence="optional" />
|
||||||
|
<parameter type="string" name="subject" occurrence="optional" />
|
||||||
|
<parameter type="string" name="from" occurrence="optional" />
|
||||||
|
<parameter type="string" name="replacement" />
|
||||||
|
</action>
|
||||||
|
|
||||||
|
<action name="enclose">
|
||||||
|
<parameter type="string" name="subject" occurrence="optional" />
|
||||||
|
<parameter type="stringlist" name="headers" occurrence="optional" />
|
||||||
|
<parameter type="string" name="text" />
|
||||||
|
</action>
|
||||||
|
|
||||||
|
<action name="extracttext">
|
||||||
|
<parameter type="tag" name="first" regex="first" occurrence="optional" />
|
||||||
|
<parameter type="number" name="number" occurrence="optional" />
|
||||||
|
<parameter type="string" name="varname" />
|
||||||
|
</action>
|
||||||
|
</extension>
|
||||||
@@ -322,5 +322,148 @@
|
|||||||
"invalid_nexthop": "\"Next hop\"-format er ugyldig",
|
"invalid_nexthop": "\"Next hop\"-format er ugyldig",
|
||||||
"img_dimensions_exceeded": "Bildet overskriver maksimal bildestørrelse",
|
"img_dimensions_exceeded": "Bildet overskriver maksimal bildestørrelse",
|
||||||
"img_size_exceeded": "Bildet overskrider maksimal filstørrelse"
|
"img_size_exceeded": "Bildet overskrider maksimal filstørrelse"
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"logs": "Logger",
|
||||||
|
"update_available": "En oppdatering er tilgjengelig",
|
||||||
|
"service": "Tjeneste",
|
||||||
|
"show_ip": "Vis offentlig IP",
|
||||||
|
"solr_dead": "Solr starter, er deaktivert eller døde",
|
||||||
|
"memory": "Minne",
|
||||||
|
"online_users": "Tilkoblede brukere",
|
||||||
|
"restart_container": "Omstart",
|
||||||
|
"size": "Størrelse",
|
||||||
|
"solr_status": "Solr-status",
|
||||||
|
"started_at": "Startet ved",
|
||||||
|
"started_on": "Startet den",
|
||||||
|
"static_logs": "Statiske logger",
|
||||||
|
"success": "Suksess",
|
||||||
|
"system_containers": "System og kontainere",
|
||||||
|
"timezone": "Tidssone",
|
||||||
|
"uptime": "Oppetid",
|
||||||
|
"no_update_available": "Systemet kjører siste versjon",
|
||||||
|
"update_failed": "Kunne ikke se etter oppdateringer",
|
||||||
|
"username": "Brukernavn",
|
||||||
|
"wip": "Foreløpig under utvikling"
|
||||||
|
},
|
||||||
|
"diagnostics": {
|
||||||
|
"dns_records_24hours": "Vennligst vær oppmerksom på at endringer gjort i DNS kan ta opp til 24 timer før riktig status vises på denne siden. Den er ment som en måte for deg å enkelt se hvordan du kan sette opp DNS-oppføringene dine og se at alle oppføringer er korrekt lagret i DNS.",
|
||||||
|
"cname_from_a": "Verdi hentet fra A/AAAA-oppføring. Dette er støttet så lenge oppføringen peker til riktig ressurs.",
|
||||||
|
"dns_records_docs": "Vennligst også se <a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">dokumentasjonen</a>.",
|
||||||
|
"dns_records": "DNS-oppføringer",
|
||||||
|
"dns_records_data": "Korrekte data",
|
||||||
|
"dns_records_name": "Navn",
|
||||||
|
"dns_records_status": "Nåværende status",
|
||||||
|
"dns_records_type": "Type",
|
||||||
|
"optional": "Denne oppføringen er valgfri."
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"bcc_dest_format": "BCC-destinasjon må være en enkelt, gyldig epostadresse.<br>Hvis du trenger å sende en kopi til flere adresser, opprett et alias og bruk det her.",
|
||||||
|
"pushover_info": "Innstillinger for pushvarslinger vil gjelde alle rene (ikke-spam) eposter levert til <b>%s</b>, inkludert aliaser (delte, ikke-delte, taggede).",
|
||||||
|
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Info</div> Du kan definere transportmappinger for et spesifikt mål for dette domenet. Hvis dette ikke er definert, blir det gjort et MX-oppslag.",
|
||||||
|
"delete2duplicates": "Slett duplikater på målvert",
|
||||||
|
"description": "Beskrivelse",
|
||||||
|
"disable_login": "Ikke tillat innlogging (innkommende epost blir likevel mottatt)",
|
||||||
|
"domain_admin": "Endre domeneadministrator",
|
||||||
|
"max_mailboxes": "Maks antall mailbokser",
|
||||||
|
"quota_warning_bcc_info": "Advarsler blir sendt som separate kopier til de følgende mottakerne. Emnet vil få lagt til det korresponderende brukernavnet i parantes, for eksempel: <code>Kvotevarsel (user@example.com)</code>.",
|
||||||
|
"domain_footer_skip_replies": "Ignorer bunntekst ved svar på epost",
|
||||||
|
"extended_sender_acl": "Eksterne avsenderadresser",
|
||||||
|
"extended_sender_acl_info": "En DKIM-domenenøkkel bør importeres, hvis tilgjengelig.<br>\n Husk å legge denne serveren til den korresponderende SPF TXT-oppføringen.<br>\n Når et domene eller aliasdomene legges til på denne serveren, og det overlapper med en ekstern adresse, blir den eksterne adressen fjernet.<br>\n Bruk @domain.tld for å tillate sending som *@domain.tld.",
|
||||||
|
"password_repeat": "Bekreft passord (gjenta)",
|
||||||
|
"pushover_title": "Varslingstittel",
|
||||||
|
"pushover_vars": "Når et avsenderfilter ikke er definert, vil alle epostere bli vurdert.<br>Regex-filtre såvel så eksakte avsendersjekker kan bli individuelt definert og vil bli vurdert sekvensielt. De er ikke avhengige av hverandre.<br>Tilgjengelige variabler for tekst og tittel (vennligst observer policyer for databeskyttelse)",
|
||||||
|
"admin": "Endre administrator",
|
||||||
|
"domain_footer_info": "Bunntekst for hele domenet leggese til alle utgående eposter assosiert med en adresse innenfor dette domenet. <br> De følgende variablene kan brukes for bunnteksten:",
|
||||||
|
"domain_footer_info_vars": {
|
||||||
|
"custom": "{= foo =} - Hvis mailboksen har en spesialattributt \"foo\" med verdi \"bar\", vil den vise \"bar\"",
|
||||||
|
"auth_user": "{= auth_user =} - Autentisert brukernavn spesifisert av en MTA",
|
||||||
|
"from_user": "{= from_user =} - Fra brukerdelen av konvolutten, f.eks. for \"moo@mailcow.tld\" vil den returnere \"moo\"",
|
||||||
|
"from_name": "{= from_name =} - Fra-navn fra konvolutten, f.eks. for \"Mailcow <moo@mailcow.tld>\" vil den vise \"Mailcow\"",
|
||||||
|
"from_addr": "{= from_addr =} - Fra adressedelen av konvolutten",
|
||||||
|
"from_domain": "{= from_domain =} - Fra domene-delen av konvolutten"
|
||||||
|
},
|
||||||
|
"mailbox_relayhost_info": "Aktiveres kun for mailboksen og direkte aliaser, overstyrer domene-videresendingsvert.",
|
||||||
|
"mbox_rl_info": "Denne begrensningen gjelder for SASL-innloggingsnavnet, dersom det er likt noen \"from\"-adresser benyttet av den innloggede brukeren. En mailboks-begrensning overstyrer en domene-begrensning.",
|
||||||
|
"allow_from_smtp_info": "La stå tom for å tillate alle avsendere.<br>IPv4/IPv6-adresser og -nettverk.",
|
||||||
|
"domain": "Endre domene",
|
||||||
|
"encryption": "Kryptering",
|
||||||
|
"exclude": "Ekskluder objekter (regex)",
|
||||||
|
"footer_exclude": "Ekskluder fra bunntekst",
|
||||||
|
"gal_info": "GAL inneholder alle objeker i et domene og kan ikke redigeres av noen brukere. Ledig/opptatt-informasjon i SOGo mangler dersom den deaktiveres! <b>Start SOGo på nytt for å aktivere endringene.</b>",
|
||||||
|
"grant_types": "Grant-typer",
|
||||||
|
"hostname": "Vertsnavn",
|
||||||
|
"inactive": "Inaktiv",
|
||||||
|
"kind": "Type",
|
||||||
|
"last_modified": "Sist endret",
|
||||||
|
"lookup_mx": "Målet er et regex-uttrykk for å matche mot MX_navnet (<code>*\\.google\\.com</code> for å route all epost som skal til en MX-server som slutter på google.com, via dette målet)",
|
||||||
|
"mailbox": "Endre mailboks",
|
||||||
|
"mailbox_quota_def": "Standardkvote for mailboks",
|
||||||
|
"max_quota": "Maks kvote pr. mailboks (MiB)",
|
||||||
|
"maxage": "Maksimal alder for meldinger, i dager, som vil hentes fra ekstern<br><small>(0 = ignorer alder)</small>",
|
||||||
|
"maxbytespersecond": "Maks bytes pr. sekund <br><small>(0 = ubegrenset)</small>",
|
||||||
|
"pushover_sender_array": "Bare vurder de følgende avsenderadressene <small>(komma-separert)</small>",
|
||||||
|
"pushover_sender_regex": "Vurder følgende avsender-regex",
|
||||||
|
"pushover_text": "Varslingstekst",
|
||||||
|
"pushover_sound": "Lyd",
|
||||||
|
"pushover_verify": "Bekreft identifikasjon",
|
||||||
|
"quota_mb": "Kvote (MiB)",
|
||||||
|
"quota_warning_bcc": "Kvotevarsling BCC",
|
||||||
|
"ratelimit": "Mengdebegrensning",
|
||||||
|
"domain_footer": "Bunntekst for hele domenet",
|
||||||
|
"private_comment": "Privat kommentar",
|
||||||
|
"public_comment": "Offentlig kommentar",
|
||||||
|
"client_id": "Klient-ID",
|
||||||
|
"full_name": "Fullt navn",
|
||||||
|
"gal": "Global adresseliste",
|
||||||
|
"max_aliases": "Maks. antall aliaser",
|
||||||
|
"mins_interval": "Intervall (min)",
|
||||||
|
"multiple_bookings": "Flere bookinger",
|
||||||
|
"none_inherit": "Ingen / arve",
|
||||||
|
"acl": "ACL (rettighet)",
|
||||||
|
"active": "Aktiv",
|
||||||
|
"advanced_settings": "Avanserte innstillinger",
|
||||||
|
"alias": "Endre alias",
|
||||||
|
"allow_from_smtp": "Tillat kun disse IPene å bruke <b>SMTP</b>",
|
||||||
|
"allowed_protocols": "Tillatte protokoller",
|
||||||
|
"app_name": "Appnavn",
|
||||||
|
"app_passwd": "App-passord",
|
||||||
|
"app_passwd_protocols": "Tillatte protokoller for app-passord",
|
||||||
|
"automap": "Prøv å automatisk mappe opp mapper (\"Sent items\", \"Sent\" => \"Sendt\" etc.)",
|
||||||
|
"backup_mx_options": "Videresendingsalternativer",
|
||||||
|
"client_secret": "Klient-hemmelighet",
|
||||||
|
"comment_info": "En privat kommentar er ikke synlig for brukeren, mens en offentlig kommentar vises som et tooltip når man holder muspekeren over det",
|
||||||
|
"created_on": "Opprettet den",
|
||||||
|
"custom_attributes": "Valgfrie attributter",
|
||||||
|
"delete1": "Slett fra kilde når fullført",
|
||||||
|
"delete2": "Slett meldinger på målvert som ikke finnes på kildeverten",
|
||||||
|
"delete_ays": "Vennligst bekreft slettingen.",
|
||||||
|
"domain_footer_html": "HTML-bunntekst",
|
||||||
|
"domain_footer_plain": "PLAIN-bunntekst",
|
||||||
|
"domain_quota": "Domenekvote",
|
||||||
|
"domains": "Domener",
|
||||||
|
"dont_check_sender_acl": "Deaktivere sendersjekk for domene %s (+ aliasdomener)",
|
||||||
|
"edit_alias_domain": "Endre aliasdomene",
|
||||||
|
"force_pw_update": "Tving endring av passord ved neste innlogging",
|
||||||
|
"force_pw_update_info": "Denne brukeren vil bare kunne logge inn på %s. App-passord kan fremdeles brukes.",
|
||||||
|
"generate": "generer",
|
||||||
|
"nexthop": "Neste hopp",
|
||||||
|
"password": "Passord",
|
||||||
|
"previous": "Forrige side",
|
||||||
|
"pushover": "Pushover",
|
||||||
|
"pushover_evaluate_x_prio": "Eskaler mail med høy prioritet [<code>X-Priority: 1</code>]",
|
||||||
|
"pushover_only_x_prio": "Bare vurder epost med høy prioritet [<code>X-Priority: 1</code>]",
|
||||||
|
"redirect_uri": "Omdirigerings-/tilbakekallings-URL",
|
||||||
|
"relay_all": "Videresend alle mottakere",
|
||||||
|
"relay_all_info": "↪ Hvis du velger å <b>ikke</b> videresende alle mottakkere, så må du legge til en (\"blind\") mailboks for hver eneste mottaker det skal videresendes for.",
|
||||||
|
"relay_domain": "Videresend dette domenet",
|
||||||
|
"relay_unknown_only": "Videresend kun ikke-eksisterende mailbokser. Eksisterende mailbokser vil bli levert lokalt.",
|
||||||
|
"relayhost": "Avsender-avhengige transportmetoder",
|
||||||
|
"remove": "Fjern",
|
||||||
|
"resource": "Ressurs",
|
||||||
|
"save": "Lagre endringer",
|
||||||
|
"scope": "Omfang",
|
||||||
|
"sender_acl": "Tillat å sende som",
|
||||||
|
"sender_acl_disabled": "<span class=\"badge fs-6 bg-danger\">Avsender-sjekk er deaktivert</span>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ services:
|
|||||||
- clamd
|
- clamd
|
||||||
|
|
||||||
rspamd-mailcow:
|
rspamd-mailcow:
|
||||||
image: mailcow/rspamd:1.96
|
image: mailcow/rspamd:1.97
|
||||||
stop_grace_period: 30s
|
stop_grace_period: 30s
|
||||||
depends_on:
|
depends_on:
|
||||||
- dovecot-mailcow
|
- dovecot-mailcow
|
||||||
@@ -90,6 +90,7 @@ services:
|
|||||||
- IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
|
- IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64}
|
||||||
- REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
|
- REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
|
||||||
- REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
|
- REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
|
||||||
|
- SPAMHAUS_DQS_KEY=${SPAMHAUS_DQS_KEY:-}
|
||||||
volumes:
|
volumes:
|
||||||
- ./data/hooks/rspamd:/hooks:Z
|
- ./data/hooks/rspamd:/hooks:Z
|
||||||
- ./data/conf/rspamd/custom/:/etc/rspamd/custom:z
|
- ./data/conf/rspamd/custom/:/etc/rspamd/custom:z
|
||||||
@@ -110,7 +111,7 @@ services:
|
|||||||
- rspamd
|
- rspamd
|
||||||
|
|
||||||
php-fpm-mailcow:
|
php-fpm-mailcow:
|
||||||
image: mailcow/phpfpm:1.87
|
image: mailcow/phpfpm:1.88
|
||||||
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:
|
||||||
- redis-mailcow
|
- redis-mailcow
|
||||||
@@ -236,7 +237,7 @@ services:
|
|||||||
- sogo
|
- sogo
|
||||||
|
|
||||||
dovecot-mailcow:
|
dovecot-mailcow:
|
||||||
image: mailcow/dovecot:nightly-20240731
|
image: mailcow/dovecot:nightly-20240807
|
||||||
depends_on:
|
depends_on:
|
||||||
- mysql-mailcow
|
- mysql-mailcow
|
||||||
- netfilter-mailcow
|
- netfilter-mailcow
|
||||||
@@ -424,7 +425,7 @@ services:
|
|||||||
condition: service_started
|
condition: service_started
|
||||||
unbound-mailcow:
|
unbound-mailcow:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
image: mailcow/acme:1.88
|
image: mailcow/acme:1.89
|
||||||
dns:
|
dns:
|
||||||
- ${IPV4_NETWORK:-172.22.1}.254
|
- ${IPV4_NETWORK:-172.22.1}.254
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
@@ -25,6 +25,16 @@ for bin in openssl curl docker git awk sha1sum grep cut; do
|
|||||||
if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi
|
if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Check Docker Version (need at least 24.X)
|
||||||
|
docker_version=$(docker -v | grep -oP '\d+\.\d+\.\d+' | cut -d '.' -f 1)
|
||||||
|
|
||||||
|
if [[ $docker_version -lt 24 ]]; then
|
||||||
|
echo -e "\e[31mCannot find Docker with a Version higher or equals 24.0.0\e[0m"
|
||||||
|
echo -e "\e[33mmailcow needs a newer Docker version to work properly...\e[0m"
|
||||||
|
echo -e "\e[31mPlease update your Docker installation... exiting\e[0m"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if docker compose > /dev/null 2>&1; then
|
if docker compose > /dev/null 2>&1; then
|
||||||
if docker compose version --short | grep -e "^2." -e "^v2." > /dev/null 2>&1; then
|
if docker compose version --short | grep -e "^2." -e "^v2." > /dev/null 2>&1; then
|
||||||
COMPOSE_VERSION=native
|
COMPOSE_VERSION=native
|
||||||
@@ -147,40 +157,44 @@ done
|
|||||||
|
|
||||||
MEM_TOTAL=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
|
MEM_TOTAL=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
|
||||||
|
|
||||||
if [ ${MEM_TOTAL} -le "2621440" ]; then
|
if [ -z "${SKIP_CLAMD}" ]; then
|
||||||
echo "Installed memory is <= 2.5 GiB. It is recommended to disable ClamAV to prevent out-of-memory situations."
|
if [ ${MEM_TOTAL} -le "2621440" ]; then
|
||||||
echo "ClamAV can be re-enabled by setting SKIP_CLAMD=n in mailcow.conf."
|
echo "Installed memory is <= 2.5 GiB. It is recommended to disable ClamAV to prevent out-of-memory situations."
|
||||||
read -r -p "Do you want to disable ClamAV now? [Y/n] " response
|
echo "ClamAV can be re-enabled by setting SKIP_CLAMD=n in mailcow.conf."
|
||||||
case $response in
|
read -r -p "Do you want to disable ClamAV now? [Y/n] " response
|
||||||
[nN][oO]|[nN])
|
case $response in
|
||||||
SKIP_CLAMD=n
|
[nN][oO]|[nN])
|
||||||
|
SKIP_CLAMD=n
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
SKIP_CLAMD=y
|
||||||
;;
|
;;
|
||||||
*)
|
esac
|
||||||
SKIP_CLAMD=y
|
else
|
||||||
;;
|
SKIP_CLAMD=n
|
||||||
esac
|
fi
|
||||||
else
|
|
||||||
SKIP_CLAMD=n
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ${MEM_TOTAL} -le "2097152" ]; then
|
if [ -z "${SKIP_SOLR}" ]; then
|
||||||
echo "Disabling Solr on low-memory system."
|
if [ ${MEM_TOTAL} -le "2097152" ]; then
|
||||||
SKIP_SOLR=y
|
echo "Disabling Solr on low-memory system."
|
||||||
elif [ ${MEM_TOTAL} -le "3670016" ]; then
|
SKIP_SOLR=y
|
||||||
echo "Installed memory is <= 3.5 GiB. It is recommended to disable Solr to prevent out-of-memory situations."
|
elif [ ${MEM_TOTAL} -le "3670016" ]; then
|
||||||
echo "Solr is a prone to run OOM and should be monitored. The default Solr heap size is 1024 MiB and should be set in mailcow.conf according to your expected load."
|
echo "Installed memory is <= 3.5 GiB. It is recommended to disable Solr to prevent out-of-memory situations."
|
||||||
echo "Solr can be re-enabled by setting SKIP_SOLR=n in mailcow.conf but will refuse to start with less than 2 GB total memory."
|
echo "Solr is a prone to run OOM and should be monitored. The default Solr heap size is 1024 MiB and should be set in mailcow.conf according to your expected load."
|
||||||
read -r -p "Do you want to disable Solr now? [Y/n] " response
|
echo "Solr can be re-enabled by setting SKIP_SOLR=n in mailcow.conf but will refuse to start with less than 2 GB total memory."
|
||||||
case $response in
|
read -r -p "Do you want to disable Solr now? [Y/n] " response
|
||||||
[nN][oO]|[nN])
|
case $response in
|
||||||
SKIP_SOLR=n
|
[nN][oO]|[nN])
|
||||||
|
SKIP_SOLR=n
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
SKIP_SOLR=y
|
||||||
;;
|
;;
|
||||||
*)
|
esac
|
||||||
SKIP_SOLR=y
|
else
|
||||||
;;
|
SKIP_SOLR=n
|
||||||
esac
|
fi
|
||||||
else
|
|
||||||
SKIP_SOLR=n
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ${SKIP_BRANCH} != y ]]; then
|
if [[ ${SKIP_BRANCH} != y ]]; then
|
||||||
|
|||||||
33
update.sh
33
update.sh
@@ -328,6 +328,16 @@ for bin in curl docker git awk sha1sum grep cut; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Check Docker Version (need at least 24.X)
|
||||||
|
docker_version=$(docker -v | grep -oP '\d+\.\d+\.\d+' | cut -d '.' -f 1)
|
||||||
|
|
||||||
|
if [[ $docker_version -lt 24 ]]; then
|
||||||
|
echo -e "\e[31mCannot find Docker with a Version higher or equals 24.0.0\e[0m"
|
||||||
|
echo -e "\e[33mmailcow needs a newer Docker version to work properly... continuing on your own risk!\e[0m"
|
||||||
|
echo -e "\e[31mPlease update your Docker installation... sleeping 10s\e[0m"
|
||||||
|
sleep 10
|
||||||
|
fi
|
||||||
|
|
||||||
export LC_ALL=C
|
export LC_ALL=C
|
||||||
DATE=$(date +%Y-%m-%d_%H_%M_%S)
|
DATE=$(date +%Y-%m-%d_%H_%M_%S)
|
||||||
BRANCH=$(cd ${SCRIPT_DIR}; git rev-parse --abbrev-ref HEAD)
|
BRANCH=$(cd ${SCRIPT_DIR}; git rev-parse --abbrev-ref HEAD)
|
||||||
@@ -399,17 +409,18 @@ while (($#)); do
|
|||||||
-f|--force - Force update, do not ask questions
|
-f|--force - Force update, do not ask questions
|
||||||
-d|--dev - Enables Developer Mode (No Checkout of update.sh for tests)
|
-d|--dev - Enables Developer Mode (No Checkout of update.sh for tests)
|
||||||
'
|
'
|
||||||
exit 1
|
exit 0
|
||||||
esac
|
esac
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
|
[[ ! -f mailcow.conf ]] && { echo -e "\e[31mmailcow.conf is missing! Is mailcow installed?\e[0m"; exit 1;}
|
||||||
|
|
||||||
chmod 600 mailcow.conf
|
chmod 600 mailcow.conf
|
||||||
source mailcow.conf
|
source mailcow.conf
|
||||||
|
|
||||||
detect_docker_compose_command
|
detect_docker_compose_command
|
||||||
|
|
||||||
[[ ! -f mailcow.conf ]] && { echo "mailcow.conf is missing! Is mailcow installed?"; exit 1;}
|
|
||||||
DOTS=${MAILCOW_HOSTNAME//[^.]};
|
DOTS=${MAILCOW_HOSTNAME//[^.]};
|
||||||
if [ ${#DOTS} -lt 1 ]; then
|
if [ ${#DOTS} -lt 1 ]; then
|
||||||
echo -e "\e[31mMAILCOW_HOSTNAME (${MAILCOW_HOSTNAME}) is not a FQDN!\e[0m"
|
echo -e "\e[31mMAILCOW_HOSTNAME (${MAILCOW_HOSTNAME}) is not a FQDN!\e[0m"
|
||||||
@@ -424,7 +435,7 @@ elif [ ${#DOTS} -eq 1 ]; then
|
|||||||
echo "Find more information about why this message exists here: https://github.com/mailcow/mailcow-dockerized/issues/1572"
|
echo "Find more information about why this message exists here: https://github.com/mailcow/mailcow-dockerized/issues/1572"
|
||||||
read -r -p "Do you want to proceed anyway? [y/N] " response
|
read -r -p "Do you want to proceed anyway? [y/N] " response
|
||||||
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
||||||
echo "OK. Procceding."
|
echo "OK. Proceeding."
|
||||||
else
|
else
|
||||||
echo "OK. Exiting."
|
echo "OK. Exiting."
|
||||||
exit 1
|
exit 1
|
||||||
@@ -807,7 +818,7 @@ if ! [ $NEW_BRANCH ]; then
|
|||||||
echo -e "\e[33mTo change that run the update.sh Script one time with the --stable parameter to switch to stable builds.\e[0m"
|
echo -e "\e[33mTo change that run the update.sh Script one time with the --stable parameter to switch to stable builds.\e[0m"
|
||||||
|
|
||||||
else
|
else
|
||||||
echo -e "\e[33mYou are receiving updates from a unsupported branch.\e[0m"
|
echo -e "\e[33mYou are receiving updates from an unsupported branch.\e[0m"
|
||||||
sleep 1
|
sleep 1
|
||||||
echo -e "\e[33mThe mailcow stack might still work but it is recommended to switch to the master branch (stable builds).\e[0m"
|
echo -e "\e[33mThe mailcow stack might still work but it is recommended to switch to the master branch (stable builds).\e[0m"
|
||||||
echo -e "\e[33mTo change that run the update.sh Script one time with the --stable parameter to switch to stable builds.\e[0m"
|
echo -e "\e[33mTo change that run the update.sh Script one time with the --stable parameter to switch to stable builds.\e[0m"
|
||||||
@@ -818,14 +829,14 @@ elif [ $FORCE ]; then
|
|||||||
echo -e "\e[31mPlease rerun the update.sh Script without the --force/-f parameter.\e[0m"
|
echo -e "\e[31mPlease rerun the update.sh Script without the --force/-f parameter.\e[0m"
|
||||||
sleep 1
|
sleep 1
|
||||||
elif [ $NEW_BRANCH == "master" ] && [ $CURRENT_BRANCH != "master" ]; then
|
elif [ $NEW_BRANCH == "master" ] && [ $CURRENT_BRANCH != "master" ]; then
|
||||||
echo -e "\e[33mYou are about to switch your mailcow Updates to the stable (master) branch.\e[0m"
|
echo -e "\e[33mYou are about to switch your mailcow updates to the stable (master) branch.\e[0m"
|
||||||
sleep 1
|
sleep 1
|
||||||
echo -e "\e[33mBefore you do: Please take a backup of all components to ensure that no Data is lost...\e[0m"
|
echo -e "\e[33mBefore you do: Please take a backup of all components to ensure that no data is lost...\e[0m"
|
||||||
sleep 1
|
sleep 1
|
||||||
echo -e "\e[31mWARNING: Please see on GitHub or ask in the communitys if a switch to master is stable or not.
|
echo -e "\e[31mWARNING: Please see on GitHub or ask in the community if a switch to master is stable or not.
|
||||||
In some rear cases a Update back to master can destroy your mailcow configuration in case of Database Upgrades etc.
|
In some rear cases an update back to master can destroy your mailcow configuration such as database upgrade, etc.
|
||||||
Normally a upgrade back to master should be safe during each full release.
|
Normally an upgrade back to master should be safe during each full release.
|
||||||
Check GitHub for Database Changes and Update only if there similar to the full release!\e[0m"
|
Check GitHub for Database changes and update only if there similar to the full release!\e[0m"
|
||||||
read -r -p "Are you sure you that want to continue upgrading to the stable (master) branch? [y/N] " response
|
read -r -p "Are you sure you that want to continue upgrading to the stable (master) branch? [y/N] " response
|
||||||
if [[ ! "${response}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
if [[ ! "${response}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
||||||
echo "OK. If you prepared yourself for that please run the update.sh Script with the --stable parameter again to trigger this process here."
|
echo "OK. If you prepared yourself for that please run the update.sh Script with the --stable parameter again to trigger this process here."
|
||||||
@@ -972,7 +983,7 @@ if [ ! $DEV ]; then
|
|||||||
echo -e "\e[31m\nOh no, what happened?\n=> You most likely added files to your local mailcow instance that were now added to the official mailcow repository. Please move them to another location before updating mailcow.\e[0m"
|
echo -e "\e[31m\nOh no, what happened?\n=> You most likely added files to your local mailcow instance that were now added to the official mailcow repository. Please move them to another location before updating mailcow.\e[0m"
|
||||||
exit 1
|
exit 1
|
||||||
elif [[ ${MERGE_RETURN} == 1 ]]; then
|
elif [[ ${MERGE_RETURN} == 1 ]]; then
|
||||||
echo -e "\e[93mPotenial conflict, trying to fix...\e[0m"
|
echo -e "\e[93mPotential conflict, trying to fix...\e[0m"
|
||||||
git status --porcelain | grep -E "UD|DU" | awk '{print $2}' | xargs rm -v
|
git status --porcelain | grep -E "UD|DU" | awk '{print $2}' | xargs rm -v
|
||||||
git add -A
|
git add -A
|
||||||
git commit -m "After update on ${DATE}" > /dev/null
|
git commit -m "After update on ${DATE}" > /dev/null
|
||||||
|
|||||||
Reference in New Issue
Block a user