# Mounted into the sidecar as /etc/rspamd/local.d/milter_headers.conf. # # rspamd writes its verdict into two headers of every message it lets through: # the action it chose and the score with the symbols behind it. SelfPost's # inbound journal reads them (Inbound > Log shows them next to the message), # and the upstream mailbox server receives them with the mail. # # rspamd removes headers of these names that a sender wrote himself before it # adds its own. Without this file the journal still lists accepted mail, with # no verdict next to it. # # The third header is the proof that the other two are rspamd's. The filter is # attached so that mail still flows when it is down, and then nothing removes # what a sender wrote: he could send his own verdict. So rspamd signs each # message - an HMAC-SHA256 of the message's queue id under a key SelfPost # generates and leaves in the directory it shares with this container - and # SelfPost reads a verdict only next to a signature it can recompute. The # signature travels on with the mail and is of no use to whoever sees it: it # fits that one queue id. # # rspamd 3.11.1, src/plugins/lua/milter_headers.lua: a custom routine is called # as function(task, common_meta) and returns error, headers to add, headers to # remove, metadata; a remove value of 0 removes every header of that name # (docs.rspamd.com/modules/milter_headers, "Custom routines"). # src/lua/lua_cryptobox.c, rspamd_lua_hash_create(): "sha256" with a key is # HMAC-SHA256 over EVP_sha256(), the key being the bytes given - here the hex # text. task:get_queue_id() is the Queue-Id the proxy took from the milter # macro "{i}" or "i" (src/libserver/milter.c, rspamd_milter_macro_http(); read # back in src/libserver/protocol.c), which Postfix sends at # end-of-message (Postfix 3.7.11, src/global/mail_params.h, DEF_MILT_EOD_MACROS # "i"). use = ["x-spamd-result", "x-rspamd-action", "selfpost-signature"]; custom { selfpost-signature = <