mailcow / mailcow-dockerized

mailcow: dockerized - šŸ® + šŸ‹ = šŸ’•
https://mailcow.email
GNU General Public License v3.0
8.25k stars 1.12k forks source link

Adding a domain wide footer leads to broken attachments #5892

Open daschr opened 4 weeks ago

daschr commented 4 weeks ago

Contribution guidelines

I've found a bug and checked that ...

Description

Adding a domain wide footer leads to broken attachments due to misplacement of the closing delimiter of the text body (below the attachment).

See https://gist.github.com/daschr/62b89f81a64c4b286f3eb12a8f785d97 In the test.eml the closing tag (----==_mimepart_66600c884d7d2_12466c31756--) is below the attachment and before the closing boundary delimiter of the attachment. This leads to that some E-Mail Clients (FairEmail, the MacOS one, and email parsers like https://github.com/stalwartlabs/mail-parser) are unable to parse the mail correctly and do not recognize the attachment.

However, if one puts the closing boundary delimiter of the body before the attachment boundary delimiter (see test-fixed.eml), the mail can be correctly displayed.

Here is the diff between the original and fixed email:

--- test.eml    2024-06-05 09:00:28.067243149 +0200
+++ test-fixed.eml  2024-06-05 09:01:22.323334986 +0200
@@ -198,6 +198,8 @@

 ----==_mimepart_66600c884da68_12466c317680--

+----==_mimepart_66600c884d7d2_12466c31756--
+
 ----==_mimepart_66600c884df14_12466c3177dc
 Content-Type: application/pdf;
  filename=test.pdf
@@ -652,6 +654,4 @@
 CiAgL0lEIFsoYlRIejVxNWd1Sm13aDlueXlxcnNTZz09KSAoYlRIejVxNWd1
 Sm13aDlueXlxcnNTZz09KV0KPj4Kc3RhcnR4cmVmCjE5NTE5CiUlRU9G

-----==_mimepart_66600c884d7d2_12466c31756--
-
 ----==_mimepart_66600c884df14_12466c3177dc--

Logs:

not helpful

Steps to reproduce:

1. go into the mailcow web interface and add a domain wide footer to one domain
2. send an email with an attachment
3. open the sent email in a Mail-Reader like FairEmail or Apple Mail (Thunderbird is able to parse the mail)
4. recognize that the attachment wont be displayed

Which branch are you using?

master

Which architecture are you using?

x86

Operating System:

Debian GNU/Linux 11 (bullseye)

Server/VM specifications:

90G RAM, 12 Cores

Is Apparmor, SELinux or similar active?

yes

Virtualization technology:

KVM

Docker version:

20.10.5+dfsg1, build 55c4c88

docker-compose version or docker compose version:

v2.12.2

mailcow version:

2024-04

Reverse proxy:

Nginx

Logs of git diff:

diff --git a/data/conf/dovecot/dovecot.conf b/data/conf/dovecot/dovecot.conf
index 729686fb..3e70bd92 100644
--- a/data/conf/dovecot/dovecot.conf
+++ b/data/conf/dovecot/dovecot.conf
@@ -11,7 +11,7 @@ auth_mechanisms = plain login
 #mail_debug = yes
 #auth_debug = yes
 log_path = syslog
-disable_plaintext_auth = yes
+disable_plaintext_auth = no
 # Uncomment on NFS share
 #mmap_disable = yes
 #mail_fsync = always
diff --git a/data/conf/postfix/main.cf b/data/conf/postfix/main.cf
index 572300db..22eead6a 100644
--- a/data/conf/postfix/main.cf
+++ b/data/conf/postfix/main.cf
@@ -173,3 +173,42 @@ parent_domain_matches_subdomains = debug_peer_list,fast_flush_domains,mynetworks

 # DO NOT EDIT ANYTHING BELOW #
 # Overrides #
+
+postscreen_dnsbl_sites = wl.mailspike.net=127.0.0.[18;19;20]*-2
+  hostkarma.junkemailfilter.com=127.0.0.1*-2
+  list.dnswl.org=127.0.[0..255].0*-2
+  list.dnswl.org=127.0.[0..255].1*-4
+  list.dnswl.org=127.0.[0..255].2*-6
+  list.dnswl.org=127.0.[0..255].3*-8
+  ix.dnsbl.manitu.net*2
+  bl.spamcop.net*2
+  bl.suomispam.net*2
+  hostkarma.junkemailfilter.com=127.0.0.2*3
+  hostkarma.junkemailfilter.com=127.0.0.4*2
+  hostkarma.junkemailfilter.com=127.0.1.2*1
+  backscatter.spameatingmonkey.net*2
+  bl.ipv6.spameatingmonkey.net*2
+  bl.spameatingmonkey.net*2
+  b.barracudacentral.org=127.0.0.2*7
+  bl.mailspike.net=127.0.0.2*5
+  bl.mailspike.net=127.0.0.[10;11;12]*4
+  dnsbl.sorbs.net=127.0.0.10*8
+  dnsbl.sorbs.net=127.0.0.5*6
+  dnsbl.sorbs.net=127.0.0.7*3
+  dnsbl.sorbs.net=127.0.0.8*2
+  dnsbl.sorbs.net=127.0.0.6*2
+  dnsbl.sorbs.net=127.0.0.9*2
+  zen.spamhaus.org=127.0.0.[10;11]*8
+  zen.spamhaus.org=127.0.0.[4..7]*6
+  zen.spamhaus.org=127.0.0.3*4
+  zen.spamhaus.org=127.0.0.2*3
+
+# User Overrides
+myhostname = mailserver.lohn24.de
+mynetworks = 127.0.0.0/8 10.10.0.0/15 172.16.0.0/12 [fd4d:6169:6c63:6f77::]/64 172.22.1.0/24
+submission_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
+smtps_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
+notify_classes = bounce
+bounce_notice_recipient = postmaster@lohn24.de
+empty_address_recipient = postmaster@lohn24.de
+smtpd_error_sleep_time = 3s
diff --git a/data/conf/rspamd/local.d/actions.conf b/data/conf/rspamd/local.d/actions.conf
index 3de63a54..87d8deda 100644
--- a/data/conf/rspamd/local.d/actions.conf
+++ b/data/conf/rspamd/local.d/actions.conf
@@ -1,3 +1,4 @@
+discard = 25;
 reject = 15;
 add_header = 8;
 greylist = 7;
diff --git a/data/conf/rspamd/local.d/composites.conf b/data/conf/rspamd/local.d/composites.conf
index cde34b57..59f056b5 100644
--- a/data/conf/rspamd/local.d/composites.conf
+++ b/data/conf/rspamd/local.d/composites.conf
@@ -3,7 +3,7 @@ MX_IMPLICIT {
   score = -0.01;
 }
 VIRUS_FOUND {
-  expression = "CLAM_VIRUS & !MAILCOW_WHITE";
+  expression = "( CLAM_VIRUS | MALUNPACKER ) & !MAILCOW_WHITE";
   score = 2000.0;
 }
 # Bad policy from free mail providers
@@ -28,7 +28,7 @@ SPOOFED_UNAUTH {
 }
 # Only apply to inbound unauthed and not whitelisted
 OLEFY_MACRO {
-  expression = "!MAILCOW_AUTH & !MAILCOW_WHITE & OLETOOLS";
+  expression = "!MAILCOW_AUTH & !MAILCOW_WHITE & ( OLETOOLS_FOUND_AUTOEXEC_MACRO | OLETOOLS_FOUND_VBA_STRING | OLETOOLS_FOUND_IOC | OLETOOLS_FOUND_FUNC )";
   score = 20.0;
   policy = "remove_weight";
 }
@@ -103,4 +103,4 @@ CLAMD_JS_MALWARE {
   expression = "CLAM_SECI_JS & !MAILCOW_WHITE";
   description = "JS malware found, Securite JS malware Flag set through ClamAV";
   score = 8;
-}
\ No newline at end of file
+}
diff --git a/data/conf/rspamd/local.d/external_services.conf b/data/conf/rspamd/local.d/external_services.conf
index 2b091ff2..28f9fff5 100644
--- a/data/conf/rspamd/local.d/external_services.conf
+++ b/data/conf/rspamd/local.d/external_services.conf
@@ -9,4 +9,27 @@ oletools {
   max_size = 3145728;
   timeout = 20.0;
   retransmits = 1;
+  patterns {
+    OLETOOLS_FOUND_AUTOEXEC_MACRO = '^A....M..$';      
+    OLETOOLS_FOUND_VBA_STRING = '^.....M.V$';      
+    OLETOOLS_FOUND_IOC = '^....IM..$'; 
+    OLETOOLS_FOUND_FUNC = '^(Document_open|Shell|Chr)$';   
+  }
+}
+
+malunpacker {
+  servers = "172.22.1.1:10055";
+  # needs to be set explicitly for Rspamd < 1.9.5
+  scan_mime_parts = false;
+  type = "icap";
+  scheme = "respmod";
+  x_client_header = true;
+  # mime-part regex matching in content-type or filename
+  # block all macros
+  max_size = 3145728;
+  timeout = 60.0;
+  retransmits = 1;
+  x_client_header = true; # Add X-Client-IP: $IP header
+  x_rcpt_header = true; # Add X-Rcpt-To: $SMTP_RCPT header
+  x_from_header = true; # Add X-Mail-From: $SMTP_FROM header
 }
diff --git a/docker-compose.yml b/docker-compose.yml
index 3efd6a42..70432f36 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -214,7 +214,7 @@ services:
         ofelia.job-exec.sogo_eautoreply.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu sogo /usr/sbin/sogo-tool update-autoreply -p /etc/sogo/sieve.creds || exit 0\""
         ofelia.job-exec.sogo_backup.schedule: "@every 24h"
         ofelia.job-exec.sogo_backup.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu sogo /usr/sbin/sogo-tool backup /sogo_backup ALL || exit 0\""
-      restart: always
+      restart: unless-stopped
       networks:
         mailcow-network:
           ipv4_address: ${IPV4_NETWORK:-172.22.1}.248
@@ -343,6 +343,8 @@ services:
           ipv4_address: ${IPV4_NETWORK:-172.22.1}.253
           aliases:
             - postfix
+      logging:
+        driver: daschr/logsqlite

     memcached-mailcow:
       image: memcached:alpine
@@ -638,7 +640,6 @@ services:
       volumes:
         - /var/run/docker.sock:/var/run/docker.sock:ro
         - /lib/modules:/lib/modules:ro
-
 networks:
   mailcow-network:
     driver: bridge

Logs of iptables -L -vn:

not helpful

Logs of ip6tables -L -vn:

not helpful

Logs of iptables -L -vn -t nat:

not helpful

Logs of ip6tables -L -vn -t nat:

not helpful

DNS check:

not helpful