Skip to content

Store generated DKIM keys in a dedicated Redis keystore - #100

Open
gott-alexander wants to merge 1 commit into
grommunio:masterfrom
gott-alexander:feature/redis-dkim-keys
Open

gott-alexander wants to merge 1 commit into
grommunio:masterfrom
gott-alexander:feature/redis-dkim-keys

Conversation

@gott-alexander

Copy link
Copy Markdown

Summary

Generated DKIM keypairs currently end up as files under the admin-api data
directory, and the UI has to ask the administrator to copy them into
/var/lib/grommunio-antispam/dkim/ by hand, because the API has no write
access to the antispam directories. This PR lets the API push generated keys
into a dedicated Redis keystore instead, from which grommunio-antispam
(rspamd dkim_signing with use_redis) reads them directly — removing the
manual copy step entirely.

Changes

  • tools/dnsHealth.py:
    • generateDkimKeys() now pushes the generated private key into the
      keystore (HSET DKIM_PRIV_KEYS <selector>.<domain> and
      HSET DKIM_SELECTORS <domain>).
    • The response changes from the bare public key string to
      {pubKey, redisStored, redisError} so clients know whether the key is
      already in place for signing (openapi.yaml updated accordingly).
    • syncDkimKeysToRedis() re-pushes all locally stored keys; called on API
      startup. The key files remain the source of truth, so the keystore is a
      rebuildable cache and signing survives the loss of Redis data.
  • res/config.yaml: new dkimRedis section (enabled, host, port,
    username, password). Disabled by default — behaviour without
    grommunio-setup wiring is unchanged (keys are generated as before and the
    UI shows the manual instructions).
  • main.py: run the sync once at startup when the keystore is enabled.

Verification

Keystore round-trip tested end to end: generate a key via the API with the
keystore enabled (redisStored: true, key visible under
DKIM_PRIV_KEYS/DKIM_SELECTORS), rspamd signs outbound mail with it
(DKIM_SIGNED), and disabling the keystore restores the previous
manual-instruction behaviour. Sync-on-start re-pushes keys after wiping the
Redis database.

Companion PRs

  • grommunio/grommunio-setup: provisions the keystore instance, writes the
    rspamd and admin-api configuration, imports pre-existing keys
  • grommunio/admin-web: shows keystore status instead of manual instructions

Comment thread tools/dnsHealth.py Outdated
def _dkimRedisConnection_():
"""Return a Redis client for the dedicated DKIM keystore, or None if
the dkimRedis configuration section is disabled."""
import redis as redislib

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use services.
with Service("redis", errors=Service.SUPPRESS_INOP) as redis:

Generate DKIM keys as before, but additionally push the private key
into a dedicated Redis instance (hashes DKIM_PRIV_KEYS /
DKIM_SELECTORS), from which grommunio-antispam's dkim_signing module
reads keys when configured with use_redis. This removes the manual
copy step into /var/lib/grommunio-antispam/dkim that the UI previously
had to demand, because the API could not write to that directory.

- generateDkimKeys returns {pubKey, redisStored, redisError} so
  clients can tell whether the key is already in place for signing
- on API startup, all locally stored keys are re-pushed; the files
  under the admin-api data directory remain the source of truth
- keystore connection is configured via the new dkimRedis section
  (disabled by default, so behaviour without grommunio-setup wiring
  is unchanged)

Support ACL username for the DKIM keystore connection

Access the DKIM keystore via the redis service hub

Replace the manually constructed redis client in _dkimRedisConnection_
with the Service("redis", errors=Service.SUPPRESS_INOP) context manager,
so keystore availability is handled by the common service framework.

Provide the DKIM keystore as its own service

Register a dedicated dkimredis service reading the dkimRedis config
section (host, port, ACL username and password) and use it from
dnsHealth, restoring the dedicated, authenticated keystore connection
while keeping the service hub mechanics.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants