Merge #2017
2017: rspamd: get dkim keys via REST API instead of filesystem r=mergify[bot] a=ghostwheel42 ## What type of PR? enhancement ## What does this PR do? rspamd now uses hashicorp's vault api v1 to get dkim keys and selectors for a domain. this allows future enhancement (multiple keys) without reconfiguring and restarting rspamd. it also makes mounting the /dkim volume into the rspamd container unnecessary. ### Related issue(s) - improves and closes #2012 - allows to implement key rotation using multiple selectors (see #1700) - allows to implement dkim for alternate domains (see #1519) - fixes and closes #1345 (selector transmitted by admin container is used) - closes #1179 (no keys on disk) - allows to implement key rotation from the outside (ie. via a helper script talking to some dns provider's api) (see #547) ## Prerequisites - [X] In case of feature or enhancement: documentation updated accordingly - [X] Unless it's docs or a minor change: add [changelog](https://mailu.io/master/contributors/workflow.html#changelog) entry file. Co-authored-by: Alexander Graf <ghostwheel42@users.noreply.github.com>master
						commit
						a5b1d36171
					
				@ -1,3 +1,3 @@
 | 
			
		||||
__all__ = [
 | 
			
		||||
    'auth', 'postfix', 'dovecot', 'fetch'
 | 
			
		||||
    'auth', 'postfix', 'dovecot', 'fetch', 'rspamd'
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,30 @@
 | 
			
		||||
from mailu import models
 | 
			
		||||
from mailu.internal import internal
 | 
			
		||||
 | 
			
		||||
import flask
 | 
			
		||||
 | 
			
		||||
def vault_error(*messages, status=404):
 | 
			
		||||
    return flask.make_response(flask.jsonify({'errors':messages}), status)
 | 
			
		||||
 | 
			
		||||
# rspamd key format:
 | 
			
		||||
# {"selectors":[{"pubkey":"...","domain":"...","valid_start":TS,"valid_end":TS,"key":"...","selector":"...","bits":...,"alg":"..."}]}
 | 
			
		||||
 | 
			
		||||
# hashicorp vault answer format:
 | 
			
		||||
# {"request_id":"...","lease_id":"","renewable":false,"lease_duration":2764800,"data":{...see above...},"wrap_info":null,"warnings":null,"auth":null}
 | 
			
		||||
 | 
			
		||||
@internal.route("/rspamd/vault/v1/dkim/<domain_name>", methods=['GET'])
 | 
			
		||||
def rspamd_dkim_key(domain_name):
 | 
			
		||||
    domain = models.Domain.query.get(domain_name) or flask.abort(vault_error('unknown domain'))
 | 
			
		||||
    key = domain.dkim_key or flask.abort(vault_error('no dkim key', status=400))
 | 
			
		||||
    return flask.jsonify({
 | 
			
		||||
        'data': {
 | 
			
		||||
            'selectors': [
 | 
			
		||||
                {
 | 
			
		||||
                    'domain'  : domain.name,
 | 
			
		||||
                    'key'     : key.decode('utf8'),
 | 
			
		||||
                    'selector': flask.current_app.config.get('DKIM_SELECTOR', 'dkim'),
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,6 @@
 | 
			
		||||
try_fallback = true;
 | 
			
		||||
path = "/dkim/$domain.$selector.key";
 | 
			
		||||
selector = "dkim"
 | 
			
		||||
try_fallback = false;
 | 
			
		||||
use_esld = false;
 | 
			
		||||
allow_username_mismatch = true;
 | 
			
		||||
use_vault = true;
 | 
			
		||||
vault_url = "http://{{ ADMIN_ADDRESS }}/internal/rspamd/vault";
 | 
			
		||||
vault_token = "mailu";
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,6 @@
 | 
			
		||||
try_fallback = true;
 | 
			
		||||
path = "/dkim/$domain.$selector.key";
 | 
			
		||||
try_fallback = false;
 | 
			
		||||
use_esld = false;
 | 
			
		||||
allow_username_mismatch = true;
 | 
			
		||||
use_vault = true;
 | 
			
		||||
vault_url = "http://{{ ADMIN_ADDRESS }}/internal/rspamd/vault";
 | 
			
		||||
vault_token = "mailu";
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1 @@
 | 
			
		||||
rspamd: get dkim keys via REST API instead of filesystem
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue