Hi everybody!
I will give a brief summary of the situation I had while preparing and proofing my brand new shiny Carbonio CE installation, in preparation for deployment. I have just registered myself on the Community Forum, so please excuse me if I am posting something already posted here, or posting in in the wrong section. Here is the details (in brief - what an oximoron):
Product
Carbonio CE 4.25.2_ZEXTRAS_202603
Environment
-
Ubuntu 22.04.5 LTS
-
Carbonio CE 4.25.2
-
OpenDKIM bundled with Carbonio
-
Amavis enabled
-
DKIM keys generated using Carbonio tools
-
DNS DKIM records published correctly
Summary
Messages sent from the Carbonio Webmail client are not DKIM signed by default, despite OpenDKIM being correctly configured and operational.
The issue appears to be caused by the Postfix Amavis reinjection service (10025) having milters explicitly disabled.
Symptoms
Messages sent through Carbonio Webmail:
-
SPF passes
-
DKIM signature absent
-
DMARC alignment cannot succeed based on DKIM
Messages sent through SMTP submission may behave differently depending on the path taken through the mail system.
Investigation
OpenDKIM was confirmed operational:
ss -lntp | grep 8465
Result:
127.0.0.1:8465 LISTEN opendkim
DKIM DNS verification:
su - zextras -c "/opt/zextras/common/sbin/opendkim-testkey -d einkaufsring.com -s mail -vvv"
Result:
key OK
Global Carbonio configuration:
carbonio prov gs <server> | grep -i milter
showed:
zimbraMtaSmtpdMilters: inet:127.0.0.1:8465
zimbraMtaNonSmtpdMilters: inet:127.0.0.1:8465
However, the Amavis reinjection service was generated as:
[127.0.0.1]:10025 inet n - n - - smtpd
...
-o smtpd_milters=
...
which disables all milters on the reinjection path.
Root Cause
Mail generated by Carbonio Webmail follows:
Webmail
-> Postfix
-> Amavis
-> 10025 reinjection
-> Internet
Since the 10025 service has:
-o smtpd_milters=
OpenDKIM never processes the reinjected message.
As a result, outbound messages leave the system unsigned.
Workaround
Modify the Postfix template:
File:
removed link
Change:
-o smtpd_milters=
to:
-o smtpd_milters=inet:127.0.0.1:8465
within the 10025 service definition.
Then regenerate configuration:
su - zextras -c "zmmtactl restart"
Verification:
su - zextras -c "postconf -P '[127.0.0.1]:10025/inet/smtpd_milters'"
Expected:
[127.0.0.1]:10025/inet/smtpd_milters = inet:127.0.0.1:8465
Result After Workaround
Messages sent from Carbonio Webmail contain valid DKIM signatures.
Gmail reports:
dkim=pass
spf=pass
and DKIM-Signature headers are present.
Expected Behaviour
Carbonio should DKIM-sign outbound mail generated through its own Webmail interface without requiring manual modification of Postfix templates.
The 10025 Amavis reinjection path should preserve DKIM signing functionality or provide a documented mechanism to enable it.
Β
One last note:
The issue was reproduced on a clean Carbonio CE deployment. OpenDKIM, DNS records, and LDAP DKIM configuration were all functioning correctly. The sole change required to restore DKIM signing was enabling milters on the 10025 reinjection service template.
Β
Thanks for your attention, and please let me know if somebody has already hit this wall, or if I could have prevented it altogether.
@silencio
I set up a CE and did the same minimal steps you describe: generated the domain key with zmdkimkeyutil and published the DNS record. After that one step, Webmail mail signed correctly.
The thing worth noting: on that install the [127.0.0.1]:10025 reinjection also has an empty smtpd_milters, exactly like yours, yet the message is still signed, because the signing happens at an earlier Postfix stage before Amavis. So the empty milter on 10025 is not what blocks signing.
Since you ran the same key generation, the difference is likely in whether that earlier signing stage is active on your server. To compare and understand better, could you please share the outputs of following:
- dpkg -l | grep -E 'carbonio-mta|carbonio-postfix' | awk '{print $2, $3}'
- su - zextras -c "carbonio prov gs $(hostname -f) zimbraServiceEnabled zimbraServiceInstalled" | grep -i opendkim
- su - zextras -c "carbonio prov gs $(hostname -f) zimbraMtaSmtpdMilters zimbraMtaNonSmtpdMilters"
- su - zextras -c "postconf smtpd_milters non_smtpd_milters"
- su - zextras -c "postconf -M" | grep -E ':10025|:10030|dkimmilter'
- su - zextras -c "postconf -P" | grep -i milter
- grep -nE 'dkimmilter|:10030|uncomment SERVICE:opendkim' /opt/zextras/common/conf/master.cf.in
Regards,
@sharif, thanks for taking the interest and the time to check π
Here are the requested outputs from my server.
Ubuntu:
-
Ubuntu 22.04 LTS
Packages:
carbonio-mta 4.2.3-1jammy
carbonio-postfix 3.10.5-2jammy
OpenDKIM service registration:
su - zextras -c "carbonio prov gs $(hostname -f) zimbraServiceEnabled zimbraServiceInstalled" | grep -i opendkim
Returns no output.
Milter configuration:
# name hermes.einkaufsring.com
zimbraMtaNonSmtpdMilters: inet:127.0.0.1:8465
zimbraMtaSmtpdMilters: inet:127.0.0.1:8465
Postfix:
smtpd_milters = inet:127.0.0.1:8465, inet:127.0.0.1:7026
non_smtpd_milters = inet:127.0.0.1:8465
Services:
[127.0.0.1]:10025 ... smtpd_milters=inet:127.0.0.1:8465 ...
[127.0.0.1]:10030 ... smtpd_milters=inet:localhost:8465 ...
syslog_name=postfix/dkimmilter
content_filter=smtp:[127.0.0.1]:10025
Per-service milter settings:
465/inet/milter_macro_daemon_name = ORIGINATING
submission/inet/milter_macro_daemon_name = ORIGINATING
[127.0.0.1]:10025/inet/smtpd_milters = inet:127.0.0.1:8465
[127.0.0.1]:10030/inet/smtpd_milters = inet:localhost:8465
[127.0.0.1]:10030/inet/syslog_name = postfix/dkimmilter
master.cf.in:
14:%%uncomment SERVICE:opendkim%% -o content_filter=scan:[%%zimbraLocalBindAddress%%]:10030
16:%%uncomment SERVICE:opendkim%% -o content_filter=scan:[%%zimbraLocalBindAddress%%]:10030
29:%%uncomment SERVICE:opendkim%% -o content_filter=scan:[%%zimbraLocalBindAddress%%]:10030
146:[%%zimbraLocalBindAddress%%]:10030 inet n - n - - smtpd
164: -o syslog_name=postfix/dkimmilter
169:%%uncomment SERVICE:opendkim%% -o content_filter=scan:[%%zimbraLocalBindAddress%%]:10030
Additional observation:
Outbound mail from Carbonio Webmail was not DKIM-signed originally.
As a workaround I changed:
removed link
10025 service:
- -o smtpd_milters=
+ -o smtpd_milters=inet:127.0.0.1:8465
After regenerating configuration with:
zmmtactl restart
Gmail immediately started reporting:
dkim=pass
spf=pass
and DKIM-Signature headers appeared in outbound mail.
What I do not understand is why the normal 10030 dkimmilter path did not sign messages before this change. Also, opendkim does not appear in zimbraServiceEnabled or zimbraServiceInstalled on this node.
Does that indicate a missing service registration or configuration issue?
Thanks for the detailed output.
It seems like the opendkim service is missing from zimbraServiceEnabled and zimbraServiceInstalled. It explains your first question too. On Carbonio CE, the Postfix template only wires your outbound services (submission and 465) into the DKIM signing stage at port 10030 when opendkim is registered as a service.
Could you please try this:
su - zextras -c 'carbonio prov ms $(hostname -f) +zimbraServiceInstalled opendkim +zimbraServiceEnabled opendkim' su - zextras -c 'zmconfigdctl restart' su - zextras -c 'zmmtactl restart'
then check:
su - zextras -c 'postconf -P | grep -E "^(submission|465)/inet/content_filter"'
Regards,
I did the sequence you kindly suggested:
root@hermes ~ # su - zextras -c 'carbonio prov ms $(hostname -f) +zimbraServiceInstalled opendkim +zimbraServiceEnabled opendkim'
root@hermes ~ # su - zextras -c 'zmconfigdctl restart'
Stopping zmconfigd...done.
Starting zmconfigd...done.
root@hermes ~ # su - zextras -c 'zmmtactl restart'
Rewriting configuration files...done.
Stopping milter server...done.
Starting milter server...done.
Stopping saslauthd...done.
Starting saslauthd...done.
/postfix-script: refreshing the Postfix mail system
root@hermes ~ # su - zextras -c 'postconf -P | grep -E "^(submission|465)/inet/content_filter"'
465/inet/content_filter = scan:[127.0.0.1]:10030
submission/inet/content_filter = scan:[127.0.0.1]:10030
and of course you were right, the intended Carbonio DKIM route is active now.So I reverted the workaround that I did, in order to prevent double-spinning:
root@hermes ~ # cp -a /opt/zextras/common/conf/master.cf.in /root/master.cf.in.before-revert-10025-dkim.$(date +%F-%H%M%S)
root@hermes ~ # sed -i '/^\[%%zimbraLocalBindAddress%%\]:10025 /,/^\[%%zimbraLocalBindAddress%%\]:10030 /s|^\([[:space:]]*-o smtpd_milters=\).*|\1|' \
/opt/zextras/common/conf/master.cf.in
root@hermes ~ # su - zextras -c 'zmmtactl restart'
Rewriting configuration files...done.
Stopping milter server...done.
Starting milter server...done.
Stopping saslauthd...done.
Starting saslauthd...done.
/postfix-script: refreshing the Postfix mail system
root@hermes ~ # su - zextras -c 'postconf -P | grep -E "^(submission|465)/inet/content_filter"'
465/inet/content_filter = scan:[127.0.0.1]:10030
submission/inet/content_filter = scan:[127.0.0.1]:10030
root@hermes ~ # su - zextras -c "postconf -P '[127.0.0.1]:10025/inet/smtpd_milters'"
[127.0.0.1]:10025/inet/smtpd_milters =
root@hermes ~ # su - zextras -c "postconf -P '[127.0.0.1]:10030/inet/smtpd_milters'"
[127.0.0.1]:10030/inet/smtpd_milters = inet:localhost:8465
... and I tried to send a test emal. And got a double DKIM signature :))) Until I remembered I had to remove OpenDKIM from the global milter settings and leave Carbonioβs own milter on 7026. So it is clean now and works like a charm. As intended, I should actually say. Thank you very much for the solution - I was dumb enough not to check the services at all to begin with.
What bugs me still - How come it was installed correctly, and never registered the service? If I was to make a "bug report" on it, it would go like this, approximately: "Fresh Carbonio CE installation resulted in OpenDKIM package being installed and operational, but opendkim was missing from zimbraServiceInstalled and zimbraServiceEnabled. As a result, %%uncomment SERVICE:opendkim%% sections in master.cf.in remained inactive, preventing mail submitted via Webmail/submission from entering the DKIM signing path. Manually registering the service with carbonio prov ms <server> +zimbraServiceInstalled opendkim +zimbraServiceEnabled opendkim immediately restored the intended routing and DKIM signing."
This might be reproducible. Is it worth investigating?
Thanks once more, and best regards.
