Skip to content

Commit 0a58aa2

Browse files
Merge pull request #6141 from mailcow/staging
2024-11
2 parents 37beed6 + be79f32 commit 0a58aa2

File tree

224 files changed

+7831
-3596
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

224 files changed

+7831
-3596
lines changed

.github/workflows/check_prs_if_on_staging.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
if: github.event.pull_request.base.ref != 'staging' #check if the target branch is not staging
1111
steps:
1212
- name: Send message
13-
uses: thollander/actions-comment-pull-request@v2.5.0
13+
uses: thollander/actions-comment-pull-request@v3.0.1
1414
with:
1515
GITHUB_TOKEN: ${{ secrets.CHECKIFPRISSTAGING_ACTION_PAT }}
1616
message: |

.github/workflows/update_postscreen_access_list.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
bash helper-scripts/update_postscreen_whitelist.sh
2323
2424
- name: Create Pull Request
25-
uses: peter-evans/create-pull-request@v6
25+
uses: peter-evans/create-pull-request@v7
2626
with:
2727
token: ${{ secrets.mailcow_action_Update_postscreen_access_cidr_pat }}
2828
commit-message: update postscreen_access.cidr

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ data/conf/rspamd/override.d/*
4545
data/conf/sogo/custom-theme.js
4646
data/conf/sogo/plist_ldap
4747
data/conf/sogo/sieve.creds
48+
data/conf/sogo/cron.creds
4849
data/conf/sogo/sogo-full.svg
4950
data/gitea/
5051
data/gogs/

data/Dockerfiles/dockerapi/main.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ async def get_container(container_id : str):
9090
if container._id == container_id:
9191
container_info = await container.show()
9292
return Response(content=json.dumps(container_info, indent=4), media_type="application/json")
93-
93+
9494
res = {
9595
"type": "danger",
9696
"msg": "no container found"
@@ -130,7 +130,7 @@ async def get_containers():
130130
async def post_containers(container_id : str, post_action : str, request: Request):
131131
global dockerapi
132132

133-
try :
133+
try:
134134
request_json = await request.json()
135135
except Exception as err:
136136
request_json = {}
@@ -191,7 +191,7 @@ async def post_container_update_stats(container_id : str):
191191

192192
stats = json.loads(await dockerapi.redis_client.get(container_id + '_stats'))
193193
return Response(content=json.dumps(stats, indent=4), media_type="application/json")
194-
194+
195195

196196
# PubSub Handler
197197
async def handle_pubsub_messages(channel: aioredis.client.PubSub):
@@ -244,7 +244,7 @@ async def handle_pubsub_messages(channel: aioredis.client.PubSub):
244244
dockerapi.logger.error("Unknwon PubSub recieved - %s" % json.dumps(data_json))
245245
else:
246246
dockerapi.logger.error("Unknwon PubSub recieved - %s" % json.dumps(data_json))
247-
247+
248248
await asyncio.sleep(0.0)
249249
except asyncio.TimeoutError:
250250
pass

data/Dockerfiles/dockerapi/modules/DockerApi.py

+142-3
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ def container_post__exec__mailq__deliver(self, request_json, **kwargs):
159159
postqueue_r = container.exec_run(["/bin/bash", "-c", "/usr/sbin/postqueue " + i], user='postfix')
160160
# todo: check each exit code
161161
res = { 'type': 'success', 'msg': 'Scheduled immediate delivery'}
162-
return Response(content=json.dumps(res, indent=4), media_type="application/json")
162+
return Response(content=json.dumps(res, indent=4), media_type="application/json")
163163
# api call: container_post - post_action: exec - cmd: mailq - task: list
164164
def container_post__exec__mailq__list(self, request_json, **kwargs):
165165
if 'container_id' in kwargs:
@@ -318,7 +318,7 @@ def container_post__exec__sieve__print(self, request_json, **kwargs):
318318

319319
if 'username' in request_json and 'script_name' in request_json:
320320
for container in self.sync_docker_client.containers.list(filters=filters):
321-
cmd = ["/bin/bash", "-c", "/usr/bin/doveadm sieve get -u '" + request_json['username'].replace("'", "'\\''") + "' '" + request_json['script_name'].replace("'", "'\\''") + "'"]
321+
cmd = ["/bin/bash", "-c", "/usr/bin/doveadm sieve get -u '" + request_json['username'].replace("'", "'\\''") + "' '" + request_json['script_name'].replace("'", "'\\''") + "'"]
322322
sieve_return = container.exec_run(cmd)
323323
return self.exec_run_handler('utf8_text_only', sieve_return)
324324
# api call: container_post - post_action: exec - cmd: maildir - task: cleanup
@@ -342,6 +342,30 @@ def container_post__exec__maildir__cleanup(self, request_json, **kwargs):
342342
cmd = ["/bin/bash", "-c", cmd_vmail]
343343
maildir_cleanup = container.exec_run(cmd, user='vmail')
344344
return self.exec_run_handler('generic', maildir_cleanup)
345+
# api call: container_post - post_action: exec - cmd: maildir - task: move
346+
def container_post__exec__maildir__move(self, request_json, **kwargs):
347+
if 'container_id' in kwargs:
348+
filters = {"id": kwargs['container_id']}
349+
elif 'container_name' in kwargs:
350+
filters = {"name": kwargs['container_name']}
351+
352+
if 'old_maildir' in request_json and 'new_maildir' in request_json:
353+
for container in self.sync_docker_client.containers.list(filters=filters):
354+
vmail_name = request_json['old_maildir'].replace("'", "'\\''")
355+
new_vmail_name = request_json['new_maildir'].replace("'", "'\\''")
356+
cmd_vmail = f"if [[ -d '/var/vmail/{vmail_name}' ]]; then /bin/mv '/var/vmail/{vmail_name}' '/var/vmail/{new_vmail_name}'; fi"
357+
358+
index_name = request_json['old_maildir'].split("/")
359+
new_index_name = request_json['new_maildir'].split("/")
360+
if len(index_name) > 1 and len(new_index_name) > 1:
361+
index_name = index_name[1].replace("'", "'\\''") + "@" + index_name[0].replace("'", "'\\''")
362+
new_index_name = new_index_name[1].replace("'", "'\\''") + "@" + new_index_name[0].replace("'", "'\\''")
363+
cmd_vmail_index = f"if [[ -d '/var/vmail_index/{index_name}' ]]; then /bin/mv '/var/vmail_index/{index_name}' '/var/vmail_index/{new_index_name}_index'; fi"
364+
cmd = ["/bin/bash", "-c", cmd_vmail + " && " + cmd_vmail_index]
365+
else:
366+
cmd = ["/bin/bash", "-c", cmd_vmail]
367+
maildir_move = container.exec_run(cmd, user='vmail')
368+
return self.exec_run_handler('generic', maildir_move)
345369
# api call: container_post - post_action: exec - cmd: rspamd - task: worker_password
346370
def container_post__exec__rspamd__worker_password(self, request_json, **kwargs):
347371
if 'container_id' in kwargs:
@@ -374,6 +398,121 @@ def container_post__exec__rspamd__worker_password(self, request_json, **kwargs):
374398
self.logger.error('failed changing Rspamd password')
375399
res = { 'type': 'danger', 'msg': 'command did not complete' }
376400
return Response(content=json.dumps(res, indent=4), media_type="application/json")
401+
# api call: container_post - post_action: exec - cmd: sogo - task: rename
402+
def container_post__exec__sogo__rename_user(self, request_json, **kwargs):
403+
if 'container_id' in kwargs:
404+
filters = {"id": kwargs['container_id']}
405+
elif 'container_name' in kwargs:
406+
filters = {"name": kwargs['container_name']}
407+
408+
if 'old_username' in request_json and 'new_username' in request_json:
409+
for container in self.sync_docker_client.containers.list(filters=filters):
410+
old_username = request_json['old_username'].replace("'", "'\\''")
411+
new_username = request_json['new_username'].replace("'", "'\\''")
412+
413+
sogo_return = container.exec_run(["/bin/bash", "-c", f"sogo-tool rename-user '{old_username}' '{new_username}'"], user='sogo')
414+
return self.exec_run_handler('generic', sogo_return)
415+
# api call: container_post - post_action: exec - cmd: doveadm - task: get_acl
416+
def container_post__exec__doveadm__get_acl(self, request_json, **kwargs):
417+
if 'container_id' in kwargs:
418+
filters = {"id": kwargs['container_id']}
419+
elif 'container_name' in kwargs:
420+
filters = {"name": kwargs['container_name']}
421+
422+
for container in self.sync_docker_client.containers.list(filters=filters):
423+
id = request_json['id'].replace("'", "'\\''")
424+
425+
shared_folders = container.exec_run(["/bin/bash", "-c", f"doveadm mailbox list -u '{id}'"])
426+
shared_folders = shared_folders.output.decode('utf-8')
427+
shared_folders = shared_folders.splitlines()
428+
429+
formatted_acls = []
430+
mailbox_seen = []
431+
for shared_folder in shared_folders:
432+
if "Shared" not in shared_folder:
433+
mailbox = shared_folder.replace("'", "'\\''")
434+
if mailbox in mailbox_seen:
435+
continue
436+
437+
acls = container.exec_run(["/bin/bash", "-c", f"doveadm acl get -u '{id}' '{mailbox}'"])
438+
acls = acls.output.decode('utf-8').strip().splitlines()
439+
if len(acls) >= 2:
440+
for acl in acls[1:]:
441+
user_id, rights = acl.split(maxsplit=1)
442+
user_id = user_id.split('=')[1]
443+
mailbox_seen.append(mailbox)
444+
formatted_acls.append({ 'user': id, 'id': user_id, 'mailbox': mailbox, 'rights': rights.split() })
445+
elif "Shared" in shared_folder and "/" in shared_folder:
446+
shared_folder = shared_folder.split("/")
447+
if len(shared_folder) < 3:
448+
continue
449+
450+
user = shared_folder[1].replace("'", "'\\''")
451+
mailbox = '/'.join(shared_folder[2:]).replace("'", "'\\''")
452+
if mailbox in mailbox_seen:
453+
continue
454+
455+
acls = container.exec_run(["/bin/bash", "-c", f"doveadm acl get -u '{user}' '{mailbox}'"])
456+
acls = acls.output.decode('utf-8').strip().splitlines()
457+
if len(acls) >= 2:
458+
for acl in acls[1:]:
459+
user_id, rights = acl.split(maxsplit=1)
460+
user_id = user_id.split('=')[1].replace("'", "'\\''")
461+
if user_id == id and mailbox not in mailbox_seen:
462+
mailbox_seen.append(mailbox)
463+
formatted_acls.append({ 'user': user, 'id': id, 'mailbox': mailbox, 'rights': rights.split() })
464+
465+
return Response(content=json.dumps(formatted_acls, indent=4), media_type="application/json")
466+
# api call: container_post - post_action: exec - cmd: doveadm - task: delete_acl
467+
def container_post__exec__doveadm__delete_acl(self, request_json, **kwargs):
468+
if 'container_id' in kwargs:
469+
filters = {"id": kwargs['container_id']}
470+
elif 'container_name' in kwargs:
471+
filters = {"name": kwargs['container_name']}
472+
473+
for container in self.sync_docker_client.containers.list(filters=filters):
474+
user = request_json['user'].replace("'", "'\\''")
475+
mailbox = request_json['mailbox'].replace("'", "'\\''")
476+
id = request_json['id'].replace("'", "'\\''")
477+
478+
if user and mailbox and id:
479+
acl_delete_return = container.exec_run(["/bin/bash", "-c", f"doveadm acl delete -u '{user}' '{mailbox}' 'user={id}'"])
480+
return self.exec_run_handler('generic', acl_delete_return)
481+
# api call: container_post - post_action: exec - cmd: doveadm - task: set_acl
482+
def container_post__exec__doveadm__set_acl(self, request_json, **kwargs):
483+
if 'container_id' in kwargs:
484+
filters = {"id": kwargs['container_id']}
485+
elif 'container_name' in kwargs:
486+
filters = {"name": kwargs['container_name']}
487+
488+
for container in self.sync_docker_client.containers.list(filters=filters):
489+
user = request_json['user'].replace("'", "'\\''")
490+
mailbox = request_json['mailbox'].replace("'", "'\\''")
491+
id = request_json['id'].replace("'", "'\\''")
492+
rights = ""
493+
494+
available_rights = [
495+
"admin",
496+
"create",
497+
"delete",
498+
"expunge",
499+
"insert",
500+
"lookup",
501+
"post",
502+
"read",
503+
"write",
504+
"write-deleted",
505+
"write-seen"
506+
]
507+
for right in request_json['rights']:
508+
right = right.replace("'", "'\\''").lower()
509+
if right in available_rights:
510+
rights += right + " "
511+
512+
if user and mailbox and id and rights:
513+
acl_set_return = container.exec_run(["/bin/bash", "-c", f"doveadm acl set -u '{user}' '{mailbox}' 'user={id}' {rights}"])
514+
return self.exec_run_handler('generic', acl_set_return)
515+
377516

378517
# Collect host stats
379518
async def get_host_stats(self, wait=5):
@@ -462,7 +601,7 @@ def recv_socket_data(c_socket, timeout):
462601
except:
463602
pass
464603
return ''.join(total_data)
465-
604+
466605
try :
467606
socket = container.exec_run([shell_cmd], stdin=True, socket=True, user=user).output._sock
468607
if not cmd.endswith("\n"):

data/Dockerfiles/dovecot/docker-entrypoint.sh

+16-3
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,15 @@ if [[ "${FLATCURVE_EXPERIMENTAL}" =~ ^([yY][eE][sS]|[yY]) ]]; then
114114
echo -e "\e[33mActivating Flatcurve as FTS Backend...\e[0m"
115115
echo -e "\e[33mDepending on your previous setup a full reindex might be needed... \e[0m"
116116
echo -e "\e[34mVisit https://docs.mailcow.email/manual-guides/Dovecot/u_e-dovecot-fts/#fts-related-dovecot-commands to learn how to reindex\e[0m"
117-
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify fts fts_flatcurve listescape replication' > /etc/dovecot/mail_plugins
117+
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify fts fts_flatcurve listescape replication lazy_expunge' > /etc/dovecot/mail_plugins
118118
echo -n 'quota imap_quota imap_acl acl zlib imap_zlib imap_sieve mail_crypt mail_crypt_acl notify mail_log fts fts_flatcurve listescape replication' > /etc/dovecot/mail_plugins_imap
119119
echo -n 'quota sieve acl zlib mail_crypt mail_crypt_acl fts fts_flatcurve notify listescape replication' > /etc/dovecot/mail_plugins_lmtp
120120
elif [[ "${SKIP_SOLR}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
121-
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify listescape replication' > /etc/dovecot/mail_plugins
121+
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify listescape replication lazy_expunge' > /etc/dovecot/mail_plugins
122122
echo -n 'quota imap_quota imap_acl acl zlib imap_zlib imap_sieve mail_crypt mail_crypt_acl notify listescape replication mail_log' > /etc/dovecot/mail_plugins_imap
123123
echo -n 'quota sieve acl zlib mail_crypt mail_crypt_acl notify listescape replication' > /etc/dovecot/mail_plugins_lmtp
124124
else
125-
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify fts fts_solr listescape replication' > /etc/dovecot/mail_plugins
125+
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify fts fts_solr listescape replication lazy_expunge' > /etc/dovecot/mail_plugins
126126
echo -n 'quota imap_quota imap_acl acl zlib imap_zlib imap_sieve mail_crypt mail_crypt_acl notify mail_log fts fts_solr listescape replication' > /etc/dovecot/mail_plugins_imap
127127
echo -n 'quota sieve acl zlib mail_crypt mail_crypt_acl fts fts_solr notify listescape replication' > /etc/dovecot/mail_plugins_lmtp
128128
fi
@@ -371,6 +371,8 @@ EOF
371371
# Create random master Password for SOGo SSO
372372
RAND_PASS=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 32 | head -n 1)
373373
echo -n ${RAND_PASS} > /etc/phpfpm/sogo-sso.pass
374+
# Creating additional creds file for SOGo notify crons (calendars, etc)
375+
echo -n ${RAND_USER}@mailcow.local:${RAND_PASS} > /etc/sogo/cron.creds
374376
cat <<EOF > /etc/dovecot/sogo-sso.conf
375377
# Autogenerated by mailcow
376378
passdb {
@@ -405,6 +407,17 @@ else
405407
chown 401 /mail_crypt/ecprivkey.pem /mail_crypt/ecpubkey.pem
406408
fi
407409

410+
# Fix OpenSSL 3.X TLS1.0, 1.1 support (https://community.mailcow.email/d/4062-hi-all/20)
411+
if grep -qE 'ssl_min_protocol\s*=\s*(TLSv1|TLSv1\.1)\s*$' /etc/dovecot/dovecot.conf /etc/dovecot/extra.conf; then
412+
sed -i '/\[openssl_init\]/a ssl_conf = ssl_configuration' /etc/ssl/openssl.cnf
413+
414+
echo "[ssl_configuration]" >> /etc/ssl/openssl.cnf
415+
echo "system_default = tls_system_default" >> /etc/ssl/openssl.cnf
416+
echo "[tls_system_default]" >> /etc/ssl/openssl.cnf
417+
echo "MinProtocol = TLSv1" >> /etc/ssl/openssl.cnf
418+
echo "CipherString = DEFAULT@SECLEVEL=0" >> /etc/ssl/openssl.cnf
419+
fi
420+
408421
# Compile sieve scripts
409422
sievec /var/vmail/sieve/global_sieve_before.sieve
410423
sievec /var/vmail/sieve/global_sieve_after.sieve

data/Dockerfiles/phpfpm/Dockerfile

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
FROM php:8.2-fpm-alpine3.18
1+
FROM php:8.2-fpm-alpine3.20
22

33
LABEL maintainer = "The Infrastructure Company GmbH <[email protected]>"
44

55
# renovate: datasource=github-tags depName=krakjoe/apcu versioning=semver-coerced extractVersion=^v(?<version>.*)$
6-
ARG APCU_PECL_VERSION=5.1.23
6+
ARG APCU_PECL_VERSION=5.1.24
77
# renovate: datasource=github-tags depName=Imagick/imagick versioning=semver-coerced extractVersion=(?<version>.*)$
88
ARG IMAGICK_PECL_VERSION=3.7.0
99
# renovate: datasource=github-tags depName=php/pecl-mail-mailparse versioning=semver-coerced extractVersion=^v(?<version>.*)$
10-
ARG MAILPARSE_PECL_VERSION=3.1.6
10+
ARG MAILPARSE_PECL_VERSION=3.1.8
1111
# renovate: datasource=github-tags depName=php-memcached-dev/php-memcached versioning=semver-coerced extractVersion=^v(?<version>.*)$
1212
ARG MEMCACHED_PECL_VERSION=3.2.0
1313
# renovate: datasource=github-tags depName=phpredis/phpredis versioning=semver-coerced extractVersion=(?<version>.*)$
14-
ARG REDIS_PECL_VERSION=6.0.2
14+
ARG REDIS_PECL_VERSION=6.1.0
1515
# renovate: datasource=github-tags depName=composer/composer versioning=semver-coerced extractVersion=(?<version>.*)$
1616
ARG COMPOSER_VERSION=2.6.6
1717

data/Dockerfiles/phpfpm/docker-entrypoint.sh

+11-2
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,25 @@ done
1010

1111
# Do not attempt to write to slave
1212
if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
13-
REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT}"
13+
REDIS_HOST=$REDIS_SLAVEOF_IP
14+
REDIS_PORT=$REDIS_SLAVEOF_PORT
1415
else
15-
REDIS_CMDLINE="redis-cli -h redis -p 6379"
16+
REDIS_HOST="redis"
17+
REDIS_PORT="6379"
1618
fi
19+
REDIS_CMDLINE="redis-cli -h ${REDIS_HOST} -p ${REDIS_PORT}"
1720

1821
until [[ $(${REDIS_CMDLINE} PING) == "PONG" ]]; do
1922
echo "Waiting for Redis..."
2023
sleep 2
2124
done
2225

26+
# Set redis session store
27+
echo -n '
28+
session.save_handler = redis
29+
session.save_path = "tcp://'${REDIS_HOST}':'${REDIS_PORT}'"
30+
' > /usr/local/etc/php/conf.d/session_store.ini
31+
2332
# Check mysql_upgrade (master and slave)
2433
CONTAINER_ID=
2534
until [[ ! -z "${CONTAINER_ID}" ]] && [[ "${CONTAINER_ID}" =~ ^[[:alnum:]]*$ ]]; do

data/Dockerfiles/postfix/docker-entrypoint.sh

+11
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,15 @@ if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
1212
cp /etc/syslog-ng/syslog-ng-redis_slave.conf /etc/syslog-ng/syslog-ng.conf
1313
fi
1414

15+
# Fix OpenSSL 3.X TLS1.0, 1.1 support (https://community.mailcow.email/d/4062-hi-all/20)
16+
if grep -qE '\!SSLv2|\!SSLv3|>=TLSv1(\.[0-1])?$' /opt/postfix/conf/main.cf /opt/postfix/conf/extra.cf; then
17+
sed -i '/\[openssl_init\]/a ssl_conf = ssl_configuration' /etc/ssl/openssl.cnf
18+
19+
echo "[ssl_configuration]" >> /etc/ssl/openssl.cnf
20+
echo "system_default = tls_system_default" >> /etc/ssl/openssl.cnf
21+
echo "[tls_system_default]" >> /etc/ssl/openssl.cnf
22+
echo "MinProtocol = TLSv1" >> /etc/ssl/openssl.cnf
23+
echo "CipherString = DEFAULT@SECLEVEL=0" >> /etc/ssl/openssl.cnf
24+
fi
25+
1526
exec "$@"

data/Dockerfiles/rspamd/Dockerfile

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
FROM debian:bookworm-slim
2-
LABEL maintainer = "The Infrastructure Company GmbH <[email protected]>"
2+
LABEL maintainer="The Infrastructure Company GmbH <[email protected]>"
33

44
ARG DEBIAN_FRONTEND=noninteractive
5-
ARG RSPAMD_VER=rspamd_3.9.1-1~82f43560f
5+
ARG RSPAMD_VER=rspamd_3.10.2-1~b8a232043
66
ARG CODENAME=bookworm
77
ENV LC_ALL=C
88

data/Dockerfiles/sogo/Dockerfile

+3-2
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,14 @@ RUN echo "Building from repository $SOGO_DEBIAN_REPOSITORY" \
3333
&& gosu nobody true \
3434
&& mkdir /usr/share/doc/sogo \
3535
&& touch /usr/share/doc/sogo/empty.sh \
36-
&& apt-key adv --keyserver keys.openpgp.org --recv-key 74FFC6D72B925A34B5D356BDF8A27B36A6E2EAE9 \
36+
&& wget http://www.axis.cz/linux/debian/axis-archive-keyring.deb -O /tmp/axis-archive-keyring.deb \
37+
&& apt install -y /tmp/axis-archive-keyring.deb \
3738
&& echo "deb [trusted=yes] ${SOGO_DEBIAN_REPOSITORY} ${DEBIAN_VERSION} sogo-v5" > /etc/apt/sources.list.d/sogo.list \
3839
&& apt-get update && apt-get install -y --no-install-recommends \
3940
sogo \
4041
sogo-activesync \
4142
&& apt-get autoclean \
42-
&& rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/sogo.list \
43+
&& rm -rf /var/lib/apt/lists/* \
4344
&& touch /etc/default/locale
4445

4546
COPY ./bootstrap-sogo.sh /bootstrap-sogo.sh

data/Dockerfiles/sogo/docker-entrypoint.sh

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
1010
cp /etc/syslog-ng/syslog-ng-redis_slave.conf /etc/syslog-ng/syslog-ng.conf
1111
fi
1212

13+
echo "$TZ" > /etc/timezone
14+
1315
# Run hooks
1416
for file in /hooks/*; do
1517
if [ -x "${file}" ]; then

data/conf/postfix/main.cf

+2
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ smtputf8_enable = no
170170
submission_smtpd_tls_mandatory_protocols = >=TLSv1.2
171171
smtps_smtpd_tls_mandatory_protocols = >=TLSv1.2
172172
parent_domain_matches_subdomains = debug_peer_list,fast_flush_domains,mynetworks,qmqpd_authorized_clients
173+
# This Option is added to correctly set the X-Original-To Header when mails are send to lmtp (dovecot)
174+
lmtp_destination_recipient_limit=1
173175

174176
# DO NOT EDIT ANYTHING BELOW #
175177
# Overrides #

0 commit comments

Comments
 (0)