mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-21 07:55:00 +00:00
email: Fix DKIM signing by setting correct ownership on private keys
See the spam score for an email sent with these settings: https://www.mail-tester.com/test-jy6unbdzu Tests done: 1. Install the email app with version 4, then check out the files: ``` ls -la /var/lib/rspamd/dkim/ ; cat /etc/rspamd/local.d/dkim_signing.conf total 4 dr-x------ 1 _rspamd _rspamd 50 Jan 1 19:14 . drwxr-x--- 1 _rspamd _rspamd 16936 Jan 1 20:21 .. -r-------- 1 root root 1704 Jan 1 19:14 freedombox.local.dkim.key cat: /etc/rspamd/local.d/dkim_signing.conf: No such file or directory ``` 2. Apply the patches and update the app: ``` ls -la /var/lib/rspamd/dkim/ ; cat /etc/rspamd/local.d/dkim_signing.conf total 4 dr-x------ 1 _rspamd _rspamd 50 Jan 1 19:14 . drwxr-x--- 1 _rspamd _rspamd 16936 Jan 1 20:22 .. -r-------- 1 _rspamd _rspamd 1704 Jan 1 19:14 freedombox.local.dkim.key allow_username_mismatch = true; sign_authenticated = true; use_domain = "header"; domain { freedombox.local { path = "/var/lib/rspamd/dkim/freedombox.local.dkim.key"; selector = "dkim"; } } ``` 3. Configure example.com as a domain under Name Services, then also change the primary domain in the email app and confirm it completes without errors. Also see: ``` ls -la /var/lib/rspamd/dkim/ ; cat /etc/rspamd/local.d/dkim_signing.conf total 8 dr-x------ 1 _rspamd _rspamd 90 Jan 1 21:15 . drwxr-x--- 1 _rspamd _rspamd 16936 Jan 1 21:17 .. -r-------- 1 _rspamd _rspamd 1704 Jan 1 21:15 example.com.dkim.key -r-------- 1 _rspamd _rspamd 1704 Jan 1 19:14 freedombox.local.dkim.key allow_username_mismatch = true; sign_authenticated = true; use_domain = "header"; domain { example.com { path = "/var/lib/rspamd/dkim/example.com.dkim.key"; selector = "dkim"; } } ``` 4. Uninstall the app and perform a fresh install, confirm it completes succesfully. The configurations in /etc/rspamd/local.d/dkim_signing.conf have been verified to work on a throw-away VPS setup. Once merged, this should be mentioned here: https://discuss.freedombox.org/t/solved-email-messages-not-signed-with-dkim/2387 Signed-off-by: Benedek Nagy <contact@nbenedek.me> [sunil: Add comment explaining allow_username_mismatch option] [sunil: Drop an unused variable, added docstrings] Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
parent
3011a59a84
commit
69a18565ea
@ -52,7 +52,7 @@ class EmailApp(plinth.app.App):
|
||||
|
||||
app_id = 'email'
|
||||
|
||||
_version = 4
|
||||
_version = 5
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize the email app."""
|
||||
@ -116,6 +116,7 @@ class EmailApp(plinth.app.App):
|
||||
'/etc/rspamd/local.d/freedombox-logging.inc',
|
||||
'/etc/rspamd/local.d/freedombox-milter-headers.conf',
|
||||
'/etc/rspamd/local.d/freedombox-redis.conf',
|
||||
'/etc/rspamd/local.d/freedombox-dkim-signing.conf'
|
||||
])
|
||||
self.add(dropin_configs)
|
||||
dropin_configs_sieve = DropinConfigs(
|
||||
@ -219,6 +220,9 @@ class EmailApp(plinth.app.App):
|
||||
# Expose to public internet
|
||||
if old_version == 0:
|
||||
self.enable()
|
||||
elif old_version < 5:
|
||||
privileged.fix_incorrect_key_ownership()
|
||||
service_privileged.try_restart('rspamd')
|
||||
|
||||
|
||||
def _get_first_admin():
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
# Do not edit this file. Manage your settings on FreedomBox or make your
|
||||
# settings changes in a different configuration file.
|
||||
|
||||
# Configure how DKIM signatures are made by rspamd on outgoing mail.
|
||||
|
||||
# When sending an email with address that is an alias, the username used for
|
||||
# authentication will not match the email address in 'From' field. rspamd
|
||||
# refuses to add a DKIM signatures to such outgoing mail. Allow DKIM signatures
|
||||
# to be made on outgoing mails where the 'From' does not match the authenticated
|
||||
# user.
|
||||
allow_username_mismatch = true;
|
||||
@ -2,13 +2,15 @@
|
||||
"""Provides privileged actions that run as root."""
|
||||
|
||||
from .aliases import setup_aliases
|
||||
from .dkim import get_dkim_public_key, setup_dkim
|
||||
from .dkim import (get_dkim_public_key, setup_dkim,
|
||||
fix_incorrect_key_ownership)
|
||||
from .domain import set_domains
|
||||
from .home import setup_home
|
||||
from .postfix import setup_postfix
|
||||
from .spam import setup_spam
|
||||
|
||||
__all__ = [
|
||||
'setup_aliases', 'get_dkim_public_key', 'setup_dkim', 'set_domains',
|
||||
'setup_home', 'setup_postfix', 'setup_spam'
|
||||
'setup_aliases', 'get_dkim_public_key', 'setup_dkim',
|
||||
'fix_incorrect_key_ownership', 'set_domains', 'setup_home',
|
||||
'setup_postfix', 'setup_spam'
|
||||
]
|
||||
|
||||
@ -10,9 +10,12 @@ import shutil
|
||||
import subprocess
|
||||
|
||||
from plinth.actions import privileged
|
||||
from plinth.privileged import service as service_privileged
|
||||
|
||||
_keys_dir = pathlib.Path('/var/lib/rspamd/dkim/')
|
||||
|
||||
rspamd_user = '_rspamd'
|
||||
|
||||
DOMAIN_PART_REGEX = r'^[a-zA-Z0-9]([-a-zA-Z0-9]{,61}[a-zA-Z0-9])?$'
|
||||
|
||||
|
||||
@ -40,7 +43,7 @@ def setup_dkim(domain: str):
|
||||
|
||||
_keys_dir.mkdir(exist_ok=True)
|
||||
_keys_dir.chmod(0o500)
|
||||
shutil.chown(_keys_dir, '_rspamd', '_rspamd')
|
||||
shutil.chown(_keys_dir, rspamd_user, rspamd_user)
|
||||
|
||||
# Default path is /var/lib/dkim/$domain.$selector.key. Default selector is
|
||||
# "dkim". Use these to simplify key management until we have a need to
|
||||
@ -55,4 +58,13 @@ def setup_dkim(domain: str):
|
||||
'rspamadm', 'dkim_keygen', '-t', 'rsa', '-b', '2048', '-s', 'dkim',
|
||||
'-d', domain, '-k', (str(key_file))
|
||||
], check=True)
|
||||
shutil.chown(key_file, rspamd_user, rspamd_user)
|
||||
key_file.chmod(0o400)
|
||||
service_privileged.try_restart('rspamd')
|
||||
|
||||
|
||||
@privileged
|
||||
def fix_incorrect_key_ownership():
|
||||
"""Set the ownership on DKIM private keys."""
|
||||
for key in _keys_dir.glob('*.dkim.key'):
|
||||
shutil.chown(key, rspamd_user, rspamd_user)
|
||||
|
||||
@ -4,6 +4,8 @@ Configures rspamd to handle incoming and outgoing spam.
|
||||
|
||||
See: http://www.postfix.org/MILTER_README.html
|
||||
See: https://rspamd.com/doc/configuration/ucl.html
|
||||
|
||||
For testing DKIM signatures: https://www.mail-tester.com/
|
||||
"""
|
||||
|
||||
import pathlib
|
||||
@ -37,7 +39,8 @@ def _setup_rspamd():
|
||||
"""Adjust configuration to include FreedomBox configuration files."""
|
||||
configs = [('milter_headers.conf', 'freedombox-milter-headers.conf'),
|
||||
('redis.conf', 'freedombox-redis.conf'),
|
||||
('logging.inc', 'freedombox-logging.inc')]
|
||||
('logging.inc', 'freedombox-logging.inc'),
|
||||
('dkim_signing.conf', 'freedombox-dkim-signing.conf')]
|
||||
base_path = pathlib.Path('/etc/rspamd/local.d')
|
||||
for orig_path, include_path in configs:
|
||||
_setup_local_include(base_path / orig_path, base_path / include_path)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user