From 89fb1322c6f486a9883e6435a73537b13fbf3582 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Fri, 8 Nov 2024 10:53:22 +0100 Subject: [PATCH] Enable password protection for Redis --- data/Dockerfiles/acme/acme.sh | 4 +-- data/Dockerfiles/acme/obtain-certificate.sh | 2 +- data/Dockerfiles/dockerapi/main.py | 4 +-- data/Dockerfiles/dovecot/clean_q_aged.sh | 2 +- data/Dockerfiles/dovecot/docker-entrypoint.sh | 4 +-- data/Dockerfiles/dovecot/quarantine_notify.py | 2 +- data/Dockerfiles/dovecot/quota_notify.py | 2 +- data/Dockerfiles/dovecot/repl_health.sh | 4 +-- .../dovecot/syslog-ng-redis_slave.conf | 2 ++ data/Dockerfiles/dovecot/syslog-ng.conf | 2 ++ data/Dockerfiles/dovecot/trim_logs.sh | 4 +-- data/Dockerfiles/netfilter/main.py | 8 ++--- data/Dockerfiles/phpfpm/docker-entrypoint.sh | 4 +-- .../postfix/syslog-ng-redis_slave.conf | 2 ++ data/Dockerfiles/postfix/syslog-ng.conf | 2 ++ data/Dockerfiles/rspamd/docker-entrypoint.sh | 12 ++++---- .../sogo/syslog-ng-redis_slave.conf | 2 ++ data/Dockerfiles/sogo/syslog-ng.conf | 2 ++ data/Dockerfiles/watchdog/watchdog.sh | 20 ++++++------- data/conf/rspamd/dynmaps/aliasexp.php | 1 + data/conf/rspamd/dynmaps/forwardinghosts.php | 1 + data/conf/rspamd/meta_exporter/pipe.php | 7 +++-- data/conf/rspamd/meta_exporter/pipe_rl.php | 1 + data/conf/rspamd/meta_exporter/pushover.php | 1 + data/web/_rspamderror.php | 1 + data/web/autodiscover.php | 1 + data/web/inc/prerequisites.inc.php | 3 +- docker-compose.yml | 29 +++++++++++++------ generate_config.sh | 16 ++++++---- helper-scripts/_cold-standby.sh | 4 +-- helper-scripts/backup_and_restore.sh | 2 +- helper-scripts/nextcloud.sh | 4 +-- helper-scripts/reset-learns.sh | 10 +++---- update.sh | 9 ++++++ 34 files changed, 111 insertions(+), 63 deletions(-) diff --git a/data/Dockerfiles/acme/acme.sh b/data/Dockerfiles/acme/acme.sh index 3c7658d84..a63c1f199 100755 --- a/data/Dockerfiles/acme/acme.sh +++ b/data/Dockerfiles/acme/acme.sh @@ -4,9 +4,9 @@ exec 5>&1 # Do not attempt to write to slave if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then - export REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT}" + export REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS}" else - export REDIS_CMDLINE="redis-cli -h redis -p 6379" + export REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS}" fi until [[ $(${REDIS_CMDLINE} PING) == "PONG" ]]; do diff --git a/data/Dockerfiles/acme/obtain-certificate.sh b/data/Dockerfiles/acme/obtain-certificate.sh index 743441197..f9eb29d1f 100644 --- a/data/Dockerfiles/acme/obtain-certificate.sh +++ b/data/Dockerfiles/acme/obtain-certificate.sh @@ -124,7 +124,7 @@ case "$SUCCESS" in ;; *) # non-zero is non-fun log_f "Failed to obtain certificate ${CERT} for domains '${CERT_DOMAINS[*]}'" - redis-cli -h redis SET ACME_FAIL_TIME "$(date +%s)" + redis-cli -h redis -a ${REDISPASS} SET ACME_FAIL_TIME "$(date +%s)" exit 100${SUCCESS} ;; esac diff --git a/data/Dockerfiles/dockerapi/main.py b/data/Dockerfiles/dockerapi/main.py index 6f7a6042c..00c2ad5e3 100644 --- a/data/Dockerfiles/dockerapi/main.py +++ b/data/Dockerfiles/dockerapi/main.py @@ -34,9 +34,9 @@ async def lifespan(app: FastAPI): # Init redis client if os.environ['REDIS_SLAVEOF_IP'] != "": - redis_client = redis = await aioredis.from_url(f"redis://{os.environ['REDIS_SLAVEOF_IP']}:{os.environ['REDIS_SLAVEOF_PORT']}/0") + redis_client = redis = await aioredis.from_url(f"redis://{os.environ['REDIS_SLAVEOF_IP']}:{os.environ['REDIS_SLAVEOF_PORT']}/0", password=os.environ['REDISPASS']) else: - redis_client = redis = await aioredis.from_url("redis://redis-mailcow:6379/0") + redis_client = redis = await aioredis.from_url("redis://redis-mailcow:6379/0", password=os.environ['REDISPASS']) # Init docker clients sync_docker_client = docker.DockerClient(base_url='unix://var/run/docker.sock', version='auto') diff --git a/data/Dockerfiles/dovecot/clean_q_aged.sh b/data/Dockerfiles/dovecot/clean_q_aged.sh index ef6b61f1f..a43853646 100755 --- a/data/Dockerfiles/dovecot/clean_q_aged.sh +++ b/data/Dockerfiles/dovecot/clean_q_aged.sh @@ -2,7 +2,7 @@ source /source_env.sh -MAX_AGE=$(redis-cli --raw -h redis-mailcow GET Q_MAX_AGE) +MAX_AGE=$(redis-cli --raw -h redis-mailcow -a ${REDISPASS} GET Q_MAX_AGE) if [[ -z ${MAX_AGE} ]]; then echo "Max age for quarantine items not defined" diff --git a/data/Dockerfiles/dovecot/docker-entrypoint.sh b/data/Dockerfiles/dovecot/docker-entrypoint.sh index 55eed7956..72d560a5f 100755 --- a/data/Dockerfiles/dovecot/docker-entrypoint.sh +++ b/data/Dockerfiles/dovecot/docker-entrypoint.sh @@ -14,9 +14,9 @@ done # Do not attempt to write to slave if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then - REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT}" + REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS}" else - REDIS_CMDLINE="redis-cli -h redis -p 6379" + REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS}" fi until [[ $(${REDIS_CMDLINE} PING) == "PONG" ]]; do diff --git a/data/Dockerfiles/dovecot/quarantine_notify.py b/data/Dockerfiles/dovecot/quarantine_notify.py index e8d743b31..dfcb1f2c6 100755 --- a/data/Dockerfiles/dovecot/quarantine_notify.py +++ b/data/Dockerfiles/dovecot/quarantine_notify.py @@ -31,7 +31,7 @@ try: while True: try: - r = redis.StrictRedis(host='redis', decode_responses=True, port=6379, db=0) + r = redis.StrictRedis(host='redis', decode_responses=True, port=6379, db=0, password=os.environ['REDISPASS']) r.ping() except Exception as ex: print('%s - trying again...' % (ex)) diff --git a/data/Dockerfiles/dovecot/quota_notify.py b/data/Dockerfiles/dovecot/quota_notify.py index 34b3e0ed9..c2c73e7a9 100755 --- a/data/Dockerfiles/dovecot/quota_notify.py +++ b/data/Dockerfiles/dovecot/quota_notify.py @@ -23,7 +23,7 @@ else: while True: try: - r = redis.StrictRedis(host='redis', decode_responses=True, port=6379, db=0) + r = redis.StrictRedis(host='redis', decode_responses=True, port=6379, db=0, password=os.environ['REDISPASS']) r.ping() except Exception as ex: print('%s - trying again...' % (ex)) diff --git a/data/Dockerfiles/dovecot/repl_health.sh b/data/Dockerfiles/dovecot/repl_health.sh index 93b66da49..447fbee5c 100755 --- a/data/Dockerfiles/dovecot/repl_health.sh +++ b/data/Dockerfiles/dovecot/repl_health.sh @@ -4,9 +4,9 @@ source /source_env.sh # Do not attempt to write to slave if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then - REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT}" + REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS}" else - REDIS_CMDLINE="redis-cli -h redis -p 6379" + REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS}" fi # Is replication active? diff --git a/data/Dockerfiles/dovecot/syslog-ng-redis_slave.conf b/data/Dockerfiles/dovecot/syslog-ng-redis_slave.conf index 519928954..4b9bf287c 100644 --- a/data/Dockerfiles/dovecot/syslog-ng-redis_slave.conf +++ b/data/Dockerfiles/dovecot/syslog-ng-redis_slave.conf @@ -20,6 +20,7 @@ destination d_redis_ui_log { host("`REDIS_SLAVEOF_IP`") persist-name("redis1") port(`REDIS_SLAVEOF_PORT`) + auth("`REDISPASS`") command("LPUSH" "DOVECOT_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n") ); }; @@ -28,6 +29,7 @@ destination d_redis_f2b_channel { host("`REDIS_SLAVEOF_IP`") persist-name("redis2") port(`REDIS_SLAVEOF_PORT`) + auth("`REDISPASS`") command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)") ); }; diff --git a/data/Dockerfiles/dovecot/syslog-ng.conf b/data/Dockerfiles/dovecot/syslog-ng.conf index 3e929e7b9..c79eb92ee 100644 --- a/data/Dockerfiles/dovecot/syslog-ng.conf +++ b/data/Dockerfiles/dovecot/syslog-ng.conf @@ -20,6 +20,7 @@ destination d_redis_ui_log { host("redis-mailcow") persist-name("redis1") port(6379) + auth("`REDISPASS`") command("LPUSH" "DOVECOT_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n") ); }; @@ -28,6 +29,7 @@ destination d_redis_f2b_channel { host("redis-mailcow") persist-name("redis2") port(6379) + auth("`REDISPASS`") command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)") ); }; diff --git a/data/Dockerfiles/dovecot/trim_logs.sh b/data/Dockerfiles/dovecot/trim_logs.sh index 9b0824e1c..1055c985a 100755 --- a/data/Dockerfiles/dovecot/trim_logs.sh +++ b/data/Dockerfiles/dovecot/trim_logs.sh @@ -10,9 +10,9 @@ catch_non_zero() { source /source_env.sh # Do not attempt to write to slave if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then - REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT}" + REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS}" else - REDIS_CMDLINE="redis-cli -h redis -p 6379" + REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS}" fi catch_non_zero "${REDIS_CMDLINE} LTRIM ACME_LOG 0 ${LOG_LINES}" catch_non_zero "${REDIS_CMDLINE} LTRIM POSTFIX_MAILLOG 0 ${LOG_LINES}" diff --git a/data/Dockerfiles/netfilter/main.py b/data/Dockerfiles/netfilter/main.py index c5667dc5f..36304bf0c 100644 --- a/data/Dockerfiles/netfilter/main.py +++ b/data/Dockerfiles/netfilter/main.py @@ -106,7 +106,7 @@ def get_ip(address): ip = ip.ipv4_mapped if ip.is_private or ip.is_loopback: return False - + return ip def ban(address): @@ -434,9 +434,9 @@ if __name__ == '__main__': redis_slaveof_ip = os.getenv('REDIS_SLAVEOF_IP', '') redis_slaveof_port = os.getenv('REDIS_SLAVEOF_PORT', '') if "".__eq__(redis_slaveof_ip): - r = redis.StrictRedis(host=os.getenv('IPV4_NETWORK', '172.22.1') + '.249', decode_responses=True, port=6379, db=0) + r = redis.StrictRedis(host=os.getenv('IPV4_NETWORK', '172.22.1') + '.249', decode_responses=True, port=6379, db=0, password=os.environ['REDISPASS']) else: - r = redis.StrictRedis(host=redis_slaveof_ip, decode_responses=True, port=redis_slaveof_port, db=0) + r = redis.StrictRedis(host=redis_slaveof_ip, decode_responses=True, port=redis_slaveof_port, db=0, password=os.environ['REDISPASS']) r.ping() pubsub = r.pubsub() except Exception as ex: @@ -452,7 +452,7 @@ if __name__ == '__main__': # clear bans in redis r.delete('F2B_ACTIVE_BANS') r.delete('F2B_PERM_BANS') - + refreshF2boptions() watch_thread = Thread(target=watch) diff --git a/data/Dockerfiles/phpfpm/docker-entrypoint.sh b/data/Dockerfiles/phpfpm/docker-entrypoint.sh index 20e9a405c..c9ca6e454 100755 --- a/data/Dockerfiles/phpfpm/docker-entrypoint.sh +++ b/data/Dockerfiles/phpfpm/docker-entrypoint.sh @@ -16,7 +16,7 @@ else REDIS_HOST="redis" REDIS_PORT="6379" fi -REDIS_CMDLINE="redis-cli -h ${REDIS_HOST} -p ${REDIS_PORT}" +REDIS_CMDLINE="redis-cli -h ${REDIS_HOST} -p ${REDIS_PORT} -a ${REDISPASS}" until [[ $(${REDIS_CMDLINE} PING) == "PONG" ]]; do echo "Waiting for Redis..." @@ -26,7 +26,7 @@ done # Set redis session store echo -n ' session.save_handler = redis -session.save_path = "tcp://'${REDIS_HOST}':'${REDIS_PORT}'" +session.save_path = "tcp://'${REDIS_HOST}':'${REDIS_PORT}'?auth='${REDISPASS}'" ' > /usr/local/etc/php/conf.d/session_store.ini # Check mysql_upgrade (master and slave) diff --git a/data/Dockerfiles/postfix/syslog-ng-redis_slave.conf b/data/Dockerfiles/postfix/syslog-ng-redis_slave.conf index cb1d1aa04..8e15932a2 100644 --- a/data/Dockerfiles/postfix/syslog-ng-redis_slave.conf +++ b/data/Dockerfiles/postfix/syslog-ng-redis_slave.conf @@ -20,6 +20,7 @@ destination d_redis_ui_log { host("`REDIS_SLAVEOF_IP`") persist-name("redis1") port(`REDIS_SLAVEOF_PORT`) + auth("`REDISPASS`") command("LPUSH" "POSTFIX_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n") ); }; @@ -28,6 +29,7 @@ destination d_redis_f2b_channel { host("`REDIS_SLAVEOF_IP`") persist-name("redis2") port(`REDIS_SLAVEOF_PORT`) + auth("`REDISPASS`") command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)") ); }; diff --git a/data/Dockerfiles/postfix/syslog-ng.conf b/data/Dockerfiles/postfix/syslog-ng.conf index 0990f1c05..fc7d1aa0f 100644 --- a/data/Dockerfiles/postfix/syslog-ng.conf +++ b/data/Dockerfiles/postfix/syslog-ng.conf @@ -20,6 +20,7 @@ destination d_redis_ui_log { host("redis-mailcow") persist-name("redis1") port(6379) + auth("`REDISPASS`") command("LPUSH" "POSTFIX_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n") ); }; @@ -28,6 +29,7 @@ destination d_redis_f2b_channel { host("redis-mailcow") persist-name("redis2") port(6379) + auth("`REDISPASS`") command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)") ); }; diff --git a/data/Dockerfiles/rspamd/docker-entrypoint.sh b/data/Dockerfiles/rspamd/docker-entrypoint.sh index cf09ee48f..513ca70a4 100755 --- a/data/Dockerfiles/rspamd/docker-entrypoint.sh +++ b/data/Dockerfiles/rspamd/docker-entrypoint.sh @@ -56,27 +56,29 @@ if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then cat < /etc/rspamd/local.d/redis.conf read_servers = "redis:6379"; write_servers = "${REDIS_SLAVEOF_IP}:${REDIS_SLAVEOF_PORT}"; +password = "${REDISPASS}"; timeout = 10; EOF - until [[ $(redis-cli -h redis-mailcow PING) == "PONG" ]]; do + until [[ $(redis-cli -h redis-mailcow -a ${REDISPASS} PING) == "PONG" ]]; do echo "Waiting for Redis @redis-mailcow..." sleep 2 done - until [[ $(redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} PING) == "PONG" ]]; do + until [[ $(redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS} PING) == "PONG" ]]; do echo "Waiting for Redis @${REDIS_SLAVEOF_IP}..." sleep 2 done - redis-cli -h redis-mailcow SLAVEOF ${REDIS_SLAVEOF_IP} ${REDIS_SLAVEOF_PORT} + redis-cli -h redis-mailcow -a ${REDISPASS} SLAVEOF ${REDIS_SLAVEOF_IP} ${REDIS_SLAVEOF_PORT} else cat < /etc/rspamd/local.d/redis.conf servers = "redis:6379"; +password = "${REDISPASS}"; timeout = 10; EOF - until [[ $(redis-cli -h redis-mailcow PING) == "PONG" ]]; do + until [[ $(redis-cli -h redis-mailcow -a ${REDISPASS} PING) == "PONG" ]]; do echo "Waiting for Redis slave..." sleep 2 done - redis-cli -h redis-mailcow SLAVEOF NO ONE + redis-cli -h redis-mailcow -a ${REDISPASS} SLAVEOF NO ONE fi # Provide additional lua modules diff --git a/data/Dockerfiles/sogo/syslog-ng-redis_slave.conf b/data/Dockerfiles/sogo/syslog-ng-redis_slave.conf index 7abfc4b59..675e4c67a 100644 --- a/data/Dockerfiles/sogo/syslog-ng-redis_slave.conf +++ b/data/Dockerfiles/sogo/syslog-ng-redis_slave.conf @@ -22,6 +22,7 @@ destination d_redis_ui_log { host("`REDIS_SLAVEOF_IP`") persist-name("redis1") port(`REDIS_SLAVEOF_PORT`) + auth("`REDISPASS`") command("LPUSH" "SOGO_LOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n") ); }; @@ -30,6 +31,7 @@ destination d_redis_f2b_channel { host("`REDIS_SLAVEOF_IP`") persist-name("redis2") port(`REDIS_SLAVEOF_PORT`) + auth("`REDISPASS`") command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)") ); }; diff --git a/data/Dockerfiles/sogo/syslog-ng.conf b/data/Dockerfiles/sogo/syslog-ng.conf index f16a2920a..8460f2f95 100644 --- a/data/Dockerfiles/sogo/syslog-ng.conf +++ b/data/Dockerfiles/sogo/syslog-ng.conf @@ -22,6 +22,7 @@ destination d_redis_ui_log { host("redis-mailcow") persist-name("redis1") port(6379) + auth("`REDISPASS`") command("LPUSH" "SOGO_LOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n") ); }; @@ -30,6 +31,7 @@ destination d_redis_f2b_channel { host("redis-mailcow") persist-name("redis2") port(6379) + auth("`REDISPASS`") command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)") ); }; diff --git a/data/Dockerfiles/watchdog/watchdog.sh b/data/Dockerfiles/watchdog/watchdog.sh index 81d65d907..46d48da6d 100755 --- a/data/Dockerfiles/watchdog/watchdog.sh +++ b/data/Dockerfiles/watchdog/watchdog.sh @@ -40,9 +40,9 @@ done # Do not attempt to write to slave if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then - REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT}" + REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS}" else - REDIS_CMDLINE="redis-cli -h redis -p 6379" + REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS}" fi until [[ $(${REDIS_CMDLINE} PING) == "PONG" ]]; do @@ -330,7 +330,7 @@ redis_checks() { touch /tmp/redis-mailcow; echo "$(tail -50 /tmp/redis-mailcow)" > /tmp/redis-mailcow host_ip=$(get_container_ip redis-mailcow) err_c_cur=${err_count} - /usr/lib/nagios/plugins/check_tcp -4 -H redis-mailcow -p 6379 -E -s "PING\n" -q "QUIT" -e "PONG" 2>> /tmp/redis-mailcow 1>&2; err_count=$(( ${err_count} + $? )) + /usr/lib/nagios/plugins/check_tcp -4 -H redis-mailcow -p 6379 -E -s "AUTH ${REDISPASS}\nPING\n" -q "QUIT" -e "PONG" 2>> /tmp/redis-mailcow 1>&2; err_count=$(( ${err_count} + $? )) [ ${err_c_cur} -eq ${err_count} ] && [ ! $((${err_count} - 1)) -lt 0 ] && err_count=$((${err_count} - 1)) diff_c=1 [ ${err_c_cur} -ne ${err_count} ] && diff_c=$(( ${err_c_cur} - ${err_count} )) progress "Redis" ${THRESHOLD} $(( ${THRESHOLD} - ${err_count} )) ${diff_c} @@ -503,12 +503,12 @@ dovecot_repl_checks() { err_count=0 diff_c=0 THRESHOLD=${DOVECOT_REPL_THRESHOLD} - D_REPL_STATUS=$(redis-cli -h redis -r GET DOVECOT_REPL_HEALTH) + D_REPL_STATUS=$(redis-cli -h redis -a ${REDISPASS} -r GET DOVECOT_REPL_HEALTH) # Reduce error count by 2 after restarting an unhealthy container trap "[ ${err_count} -gt 1 ] && err_count=$(( ${err_count} - 2 ))" USR1 while [ ${err_count} -lt ${THRESHOLD} ]; do err_c_cur=${err_count} - D_REPL_STATUS=$(redis-cli --raw -h redis GET DOVECOT_REPL_HEALTH) + D_REPL_STATUS=$(redis-cli --raw -h redis -a ${REDISPASS} GET DOVECOT_REPL_HEALTH) if [[ "${D_REPL_STATUS}" != "1" ]]; then err_count=$(( ${err_count} + 1 )) fi @@ -578,19 +578,19 @@ ratelimit_checks() { err_count=0 diff_c=0 THRESHOLD=${RATELIMIT_THRESHOLD} - RL_LOG_STATUS=$(redis-cli -h redis LRANGE RL_LOG 0 0 | jq .qid) + RL_LOG_STATUS=$(redis-cli -h redis -a ${REDISPASS} LRANGE RL_LOG 0 0 | jq .qid) # Reduce error count by 2 after restarting an unhealthy container trap "[ ${err_count} -gt 1 ] && err_count=$(( ${err_count} - 2 ))" USR1 while [ ${err_count} -lt ${THRESHOLD} ]; do err_c_cur=${err_count} RL_LOG_STATUS_PREV=${RL_LOG_STATUS} - RL_LOG_STATUS=$(redis-cli -h redis LRANGE RL_LOG 0 0 | jq .qid) + RL_LOG_STATUS=$(redis-cli -h redis -a ${REDISPASS} LRANGE RL_LOG 0 0 | jq .qid) if [[ ${RL_LOG_STATUS_PREV} != ${RL_LOG_STATUS} ]]; then err_count=$(( ${err_count} + 1 )) echo 'Last 10 applied ratelimits (may overlap with previous reports).' > /tmp/ratelimit echo 'Full ratelimit buckets can be emptied by deleting the ratelimit hash from within mailcow UI (see /debug -> Protocols -> Ratelimit):' >> /tmp/ratelimit echo >> /tmp/ratelimit - redis-cli --raw -h redis LRANGE RL_LOG 0 10 | jq . >> /tmp/ratelimit + redis-cli --raw -h redis -a ${REDISPASS} LRANGE RL_LOG 0 10 | jq . >> /tmp/ratelimit fi [ ${err_c_cur} -eq ${err_count} ] && [ ! $((${err_count} - 1)) -lt 0 ] && err_count=$((${err_count} - 1)) diff_c=1 [ ${err_c_cur} -ne ${err_count} ] && diff_c=$(( ${err_c_cur} - ${err_count} )) @@ -673,7 +673,7 @@ acme_checks() { err_count=0 diff_c=0 THRESHOLD=${ACME_THRESHOLD} - ACME_LOG_STATUS=$(redis-cli -h redis GET ACME_FAIL_TIME) + ACME_LOG_STATUS=$(redis-cli -h redis -a ${REDISPASS} GET ACME_FAIL_TIME) if [[ -z "${ACME_LOG_STATUS}" ]]; then ${REDIS_CMDLINE} SET ACME_FAIL_TIME 0 ACME_LOG_STATUS=0 @@ -685,7 +685,7 @@ acme_checks() { ACME_LOG_STATUS_PREV=${ACME_LOG_STATUS} ACME_LC=0 until [[ ! -z ${ACME_LOG_STATUS} ]] || [ ${ACME_LC} -ge 3 ]; do - ACME_LOG_STATUS=$(redis-cli -h redis GET ACME_FAIL_TIME 2> /dev/null) + ACME_LOG_STATUS=$(redis-cli -h redis -a ${REDISPASS} GET ACME_FAIL_TIME 2> /dev/null) sleep 3 ACME_LC=$((ACME_LC+1)) done diff --git a/data/conf/rspamd/dynmaps/aliasexp.php b/data/conf/rspamd/dynmaps/aliasexp.php index 947a02444..824037cf1 100644 --- a/data/conf/rspamd/dynmaps/aliasexp.php +++ b/data/conf/rspamd/dynmaps/aliasexp.php @@ -25,6 +25,7 @@ catch (PDOException $e) { // Init Redis $redis = new Redis(); $redis->connect('redis-mailcow', 6379); +$redis->auth(getenv("REDISPASS")); function parse_email($email) { if(!filter_var($email, FILTER_VALIDATE_EMAIL)) return false; diff --git a/data/conf/rspamd/dynmaps/forwardinghosts.php b/data/conf/rspamd/dynmaps/forwardinghosts.php index 10285b715..2186d7f26 100644 --- a/data/conf/rspamd/dynmaps/forwardinghosts.php +++ b/data/conf/rspamd/dynmaps/forwardinghosts.php @@ -4,6 +4,7 @@ ini_set('error_reporting', 0); $redis = new Redis(); $redis->connect('redis-mailcow', 6379); +$redis->auth(getenv("REDISPASS")); function in_net($addr, $net) { $net = explode('/', $net); diff --git a/data/conf/rspamd/meta_exporter/pipe.php b/data/conf/rspamd/meta_exporter/pipe.php index 1858ee668..4d8e2a132 100644 --- a/data/conf/rspamd/meta_exporter/pipe.php +++ b/data/conf/rspamd/meta_exporter/pipe.php @@ -24,6 +24,7 @@ catch (PDOException $e) { // Init Redis $redis = new Redis(); $redis->connect('redis-mailcow', 6379); +$redis->auth(getenv("REDISPASS")); // Functions function parse_email($email) { @@ -96,10 +97,10 @@ $rcpt_final_mailboxes = array(); foreach (json_decode($rcpts, true) as $rcpt) { // Remove tag $rcpt = preg_replace('/^(.*?)\+.*(@.*)$/', '$1$2', $rcpt); - + // Break rcpt into local part and domain part $parsed_rcpt = parse_email($rcpt); - + // Skip if not a mailcow handled domain try { if (!$redis->hGet('DOMAIN_MAP', $parsed_rcpt['domain'])) { @@ -243,7 +244,7 @@ foreach ($rcpt_final_mailboxes as $rcpt_final) { WHERE `rcpt` = :rcpt2 ORDER BY id DESC LIMIT :retention_size - ) x + ) x );'); $stmt->execute(array( ':rcpt' => $rcpt_final, diff --git a/data/conf/rspamd/meta_exporter/pipe_rl.php b/data/conf/rspamd/meta_exporter/pipe_rl.php index 5f7fd42c3..f9a21caf7 100644 --- a/data/conf/rspamd/meta_exporter/pipe_rl.php +++ b/data/conf/rspamd/meta_exporter/pipe_rl.php @@ -14,6 +14,7 @@ try { else { $redis->connect('redis-mailcow', 6379); } + $redis->auth(getenv("REDISPASS")); } catch (Exception $e) { exit; diff --git a/data/conf/rspamd/meta_exporter/pushover.php b/data/conf/rspamd/meta_exporter/pushover.php index f122b281a..af1b21ebc 100644 --- a/data/conf/rspamd/meta_exporter/pushover.php +++ b/data/conf/rspamd/meta_exporter/pushover.php @@ -24,6 +24,7 @@ catch (PDOException $e) { // Init Redis $redis = new Redis(); $redis->connect('redis-mailcow', 6379); +$redis->auth(getenv("REDISPASS")); // Functions function parse_email($email) { diff --git a/data/web/_rspamderror.php b/data/web/_rspamderror.php index 6bdfb3495..4976e0b5e 100644 --- a/data/web/_rspamderror.php +++ b/data/web/_rspamderror.php @@ -7,6 +7,7 @@ try { else { $redis->connect('redis-mailcow', 6379); } + $redis->auth(getenv("REDISPASS")); } catch (Exception $e) { exit; diff --git a/data/web/autodiscover.php b/data/web/autodiscover.php index 992524b35..6e1634bb7 100644 --- a/data/web/autodiscover.php +++ b/data/web/autodiscover.php @@ -16,6 +16,7 @@ try { else { $redis->connect('redis-mailcow', 6379); } + $redis->auth(getenv("REDISPASS")); } catch (Exception $e) { exit; diff --git a/data/web/inc/prerequisites.inc.php b/data/web/inc/prerequisites.inc.php index 9c5203e7f..d64313127 100644 --- a/data/web/inc/prerequisites.inc.php +++ b/data/web/inc/prerequisites.inc.php @@ -68,6 +68,7 @@ try { else { $redis->connect('redis-mailcow', 6379); } + $redis->auth(getenv("REDISPASS")); } catch (Exception $e) { // Stop when redis is not available @@ -321,7 +322,7 @@ $UI_TEXTS = customize('get', 'ui_texts'); if (file_exists('/web/css/themes/'.$UI_THEME.'-bootstrap.css')) $css_minifier->add('/web/css/themes/'.$UI_THEME.'-bootstrap.css'); else - $css_minifier->add('/web/css/themes/lumen-bootstrap.css'); + $css_minifier->add('/web/css/themes/lumen-bootstrap.css'); // minify css build files foreach ($css_dir as $css_file) { $css_minifier->add('/web/css/build/' . $css_file); diff --git a/docker-compose.yml b/docker-compose.yml index 31d6f56fd..ccb2a7271 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -43,6 +43,7 @@ services: redis-mailcow: image: redis:7-alpine + command: '--requirepass ${REDISPASS}' volumes: - redis-vol-1:/data/ restart: always @@ -52,6 +53,7 @@ services: - "${REDIS_PORT:-127.0.0.1:7654}:6379" environment: - TZ=${TZ} + - REDISPASS=${REDISPASS} sysctls: - net.core.somaxconn=4096 networks: @@ -80,7 +82,7 @@ services: - clamd rspamd-mailcow: - image: mailcow/rspamd:1.98 + image: mailcow/rspamd:1.99 stop_grace_period: 30s depends_on: - dovecot-mailcow @@ -91,6 +93,7 @@ services: - IPV6_NETWORK=${IPV6_NETWORK:-fd4d:6169:6c63:6f77::/64} - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-} - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-} + - REDISPASS=${REDISPASS} - SPAMHAUS_DQS_KEY=${SPAMHAUS_DQS_KEY:-} volumes: - ./data/hooks/rspamd:/hooks:Z @@ -112,7 +115,7 @@ services: - rspamd php-fpm-mailcow: - image: mailcow/phpfpm:1.91.1 + image: mailcow/phpfpm:1.92 command: "php-fpm -d date.timezone=${TZ} -d expose_php=0" depends_on: - redis-mailcow @@ -139,6 +142,7 @@ services: environment: - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-} - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-} + - REDISPASS=${REDISPASS} - LOG_LINES=${LOG_LINES:-9999} - TZ=${TZ} - DBNAME=${DBNAME} @@ -177,7 +181,7 @@ services: - phpfpm sogo-mailcow: - image: mailcow/sogo:1.127.1 + image: mailcow/sogo:1.128 environment: - DBNAME=${DBNAME} - DBUSER=${DBUSER} @@ -194,6 +198,7 @@ services: - MASTER=${MASTER:-y} - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-} - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-} + - REDISPASS=${REDISPASS} dns: - ${IPV4_NETWORK:-172.22.1}.254 volumes: @@ -224,7 +229,7 @@ services: - sogo dovecot-mailcow: - image: mailcow/dovecot:2.2 + image: mailcow/dovecot:2.21 depends_on: - mysql-mailcow - netfilter-mailcow @@ -266,6 +271,7 @@ services: - MASTER=${MASTER:-y} - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-} - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-} + - REDISPASS=${REDISPASS} - COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-mailcow-dockerized} - FLATCURVE_EXPERIMENTAL=${FLATCURVE_EXPERIMENTAL:-n} ports: @@ -308,7 +314,7 @@ services: - dovecot postfix-mailcow: - image: mailcow/postfix:1.77 + image: mailcow/postfix:1.78 depends_on: mysql-mailcow: condition: service_started @@ -330,6 +336,7 @@ services: - DBPASS=${DBPASS} - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-} - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-} + - REDISPASS=${REDISPASS} - MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME} - SPAMHAUS_DQS_KEY=${SPAMHAUS_DQS_KEY:-} cap_add: @@ -401,7 +408,7 @@ services: condition: service_started unbound-mailcow: condition: service_healthy - image: mailcow/acme:1.90 + image: mailcow/acme:1.91 dns: - ${IPV4_NETWORK:-172.22.1}.254 environment: @@ -424,6 +431,7 @@ services: - TZ=${TZ} - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-} - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-} + - REDISPASS=${REDISPASS} - SNAT_TO_SOURCE=${SNAT_TO_SOURCE:-n} - SNAT6_TO_SOURCE=${SNAT6_TO_SOURCE:-n} volumes: @@ -438,7 +446,7 @@ services: - acme netfilter-mailcow: - image: mailcow/netfilter:1.59 + image: mailcow/netfilter:1.60 stop_grace_period: 30s restart: always privileged: true @@ -450,6 +458,7 @@ services: - SNAT6_TO_SOURCE=${SNAT6_TO_SOURCE:-n} - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-} - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-} + - REDISPASS=${REDISPASS} - MAILCOW_REPLICA_IP=${MAILCOW_REPLICA_IP:-} - DISABLE_NETFILTER_ISOLATION_RULE=${DISABLE_NETFILTER_ISOLATION_RULE:-n} network_mode: "host" @@ -457,7 +466,7 @@ services: - /lib/modules:/lib/modules:ro watchdog-mailcow: - image: mailcow/watchdog:2.05 + image: mailcow/watchdog:2.06 dns: - ${IPV4_NETWORK:-172.22.1}.254 tmpfs: @@ -503,6 +512,7 @@ services: - HTTPS_PORT=${HTTPS_PORT:-443} - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-} - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-} + - REDISPASS=${REDISPASS} - EXTERNAL_CHECKS_THRESHOLD=${EXTERNAL_CHECKS_THRESHOLD:-1} - NGINX_THRESHOLD=${NGINX_THRESHOLD:-5} - UNBOUND_THRESHOLD=${UNBOUND_THRESHOLD:-5} @@ -528,7 +538,7 @@ services: - watchdog dockerapi-mailcow: - image: mailcow/dockerapi:2.09 + image: mailcow/dockerapi:2.10 security_opt: - label=disable restart: always @@ -539,6 +549,7 @@ services: - TZ=${TZ} - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-} - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-} + - REDISPASS=${REDISPASS} volumes: - /var/run/docker.sock:/var/run/docker.sock:ro networks: diff --git a/generate_config.sh b/generate_config.sh index f5a2a01b2..46a36a179 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -43,7 +43,7 @@ if docker compose > /dev/null 2>&1; then sleep 2 echo -e "\e[33mNotice: You'll have to update this Compose Version via your Package Manager manually!\e[0m" else - echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m" + echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m" echo -e "\e[31mPlease update/install it manually regarding to this doc site: https://docs.mailcow.email/install/\e[0m" exit 1 fi @@ -56,14 +56,14 @@ elif docker-compose > /dev/null 2>&1; then sleep 2 echo -e "\e[33mNotice: For an automatic update of docker-compose please use the update_compose.sh scripts located at the helper-scripts folder.\e[0m" else - echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m" + echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m" echo -e "\e[31mPlease update/install manually regarding to this doc site: https://docs.mailcow.email/install/\e[0m" exit 1 fi fi else - echo -e "\e[31mCannot find Docker Compose.\e[0m" + echo -e "\e[31mCannot find Docker Compose.\e[0m" echo -e "\e[31mPlease install it regarding to this doc site: https://docs.mailcow.email/install/\e[0m" exit 1 fi @@ -229,7 +229,7 @@ else echo -e "\033[31mCould not determine branch input..." echo -e "\033[31mExiting." exit 1 -fi +fi if [ ! -z "${MAILCOW_BRANCH}" ]; then git_branch=${MAILCOW_BRANCH} @@ -264,6 +264,12 @@ DBUSER=mailcow DBPASS=$(LC_ALL=C /dev/null | head -c 28) DBROOT=$(LC_ALL=C /dev/null | head -c 28) +# ------------------------------ +# REDIS configuration +# ------------------------------ + +REDISPASS=$(LC_ALL=C /dev/null | head -c 28) + # ------------------------------ # HTTP/S Bindings # ------------------------------ @@ -510,7 +516,7 @@ WEBAUTHN_ONLY_TRUSTED_VENDORS=n # Spamhaus Data Query Service Key # Optional: Leave empty for none -# Enter your key here if you are using a blocked ASN (OVH, AWS, Cloudflare e.g) for the unregistered Spamhaus Blocklist. +# Enter your key here if you are using a blocked ASN (OVH, AWS, Cloudflare e.g) for the unregistered Spamhaus Blocklist. # If empty, it will completely disable Spamhaus blocklists if it detects that you are running on a server using a blocked AS. # Otherwise it will work normally. SPAMHAUS_DQS_KEY= diff --git a/helper-scripts/_cold-standby.sh b/helper-scripts/_cold-standby.sh index ff0512e07..2fd1dcb67 100755 --- a/helper-scripts/_cold-standby.sh +++ b/helper-scripts/_cold-standby.sh @@ -150,7 +150,7 @@ else exit 1 fi - REMOTE_ARCH=$(ssh -o StrictHostKeyChecking=no -i "${REMOTE_SSH_KEY}" ${REMOTE_SSH_HOST} -p ${REMOTE_SSH_PORT} "uname -m") + REMOTE_ARCH=$(ssh -o StrictHostKeyChecking=no -i "${REMOTE_SSH_KEY}" ${REMOTE_SSH_HOST} -p ${REMOTE_SSH_PORT} "uname -m") } @@ -204,7 +204,7 @@ fi # Trigger a Redis save for a consistent Redis copy echo -ne "\033[1mRunning redis-cli save... \033[0m" -docker exec $(docker ps -qf name=redis-mailcow) redis-cli save +docker exec $(docker ps -qf name=redis-mailcow) redis-cli -a ${REDISPASS} save # Syncing volumes related to compose project # Same here: make sure destination exists diff --git a/helper-scripts/backup_and_restore.sh b/helper-scripts/backup_and_restore.sh index dc30d5ea1..f8deb590e 100755 --- a/helper-scripts/backup_and_restore.sh +++ b/helper-scripts/backup_and_restore.sh @@ -119,7 +119,7 @@ function backup() { ${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="pigz --rsyncable -p ${THREADS}" -Pcvpf /backup/backup_crypt.tar.gz /crypt ;;& redis|all) - docker exec $(docker ps -qf name=redis-mailcow) redis-cli save + docker exec $(docker ps -qf name=redis-mailcow) redis-cli -a ${REDISPASS} save docker run --name mailcow-backup --rm \ -v ${BACKUP_LOCATION}/mailcow-${DATE}:/backup:z \ -v $(docker volume ls -qf name=^${CMPS_PRJ}_redis-vol-1$):/redis:ro,z \ diff --git a/helper-scripts/nextcloud.sh b/helper-scripts/nextcloud.sh index 2df3ca161..b05a3c93b 100755 --- a/helper-scripts/nextcloud.sh +++ b/helper-scripts/nextcloud.sh @@ -101,11 +101,11 @@ if [[ ${NC_PURGE} == "y" ]]; then echo -e "\033[33mNot purging anything...\033[0m" exit 1 fi - docker exec -it $(docker ps -f name=redis-mailcow -q) /bin/sh -c ' cat <> mailcow.conf echo 'DISABLE_NETFILTER_ISOLATION_RULE=n' >> mailcow.conf fi + elif [[ "${option}" == "REDISPASS" ]]; then + if ! grep -q "${option}" mailcow.conf; then + echo "Adding new option \"${option}\" to mailcow.conf" + echo -e '\n# ------------------------------' >> mailcow.conf + echo '# REDIS configuration' >> mailcow.conf + echo -e '# ------------------------------\n' >> mailcow.conf + echo "REDISPASS=$(LC_ALL=C /dev/null | head -c 28)" >> mailcow.conf + fi elif ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo "${option}=n" >> mailcow.conf