10 aprile 2020 Roberto Puzzanghera 4 commenti
Questa pagina riguarda la patch DKIM inclusa nella mia patch combinata (maggiori informazioni qui). Questo argomento è avanzato ed è consigliabile tornare qui alla fine del tutto.
DKIM fornisce un metodo per validare l'identità di un nome a dominio associato a un messaggio con una autenticazione crittografata. La tecnica di validazione è basata sulla crittografia di una chiave pubblica: Il server che invia l'email aggiunge il nome a dominio al messaggio e vi affigge una firma digitale. Questa chiave è posta nell'intestazione DKIM-Signature: del messaggio. Colui che riceve il messaggio può controllare la validità della chiave pubblica leggendo un record TXT del DNS del dominio associato al messaggio.
Sei invitato a dare un'occhiata alle pagine man a partire da qmail-dkim(8) e spawn-filter(8).
Mirko Buffoni ha pubblicato in un commento una piccola modifica che consente di firmare i messaggi inviati dagli utenti autenticati e di verificare quelli degli utenti non autenticati.
Vorrei rivolgere un ringraziamento speciale a Manvendra Bhangui, l'autore della DKIM patch, per avermi assistito con grande cortesia durante tutta la configurazione.
I will show how to configure qmail-remote to sign your outgoing messages and qmail-smtpd to verify your incoming messages. Eventually, as an alternative, you can decide to set qmail-smtpd to do both things; this configuration is presented towards the bottom of this page.
In any case you have to create the domainkey signature.
domainkey
per le email in uscitaLe firme vengono create usando una chiave privata presente in un file protetto, e verificate da una chiave pubblica salvata in un record TXT nel DNS per il domino associato all'email.
Prima di poter firmare la posta, è necessario creare almeno una coppia di chiavi pubblica/privata. Si può decidere di creare una coppia di chiavi che valga per tutti i domini presenti nel mail server, oppure di usare una coppia di chiavi per ognuno dei domini.
Prima di tutto scaricare lo script (grazie a Joerg Backschues e a Tatsuya Yokota per il supporto alla firma a 2048 bit) che useremo per creare le chiavi e stampare a video il record DNS.
cd /usr/local/bin wget https://notes.sagredo.eu/files/qmail/domainkey chmod +x domainkey
Creare ora la cartella dove saranno salvate tutte le domainkeys e assegnare i privilegi di scrittura all'utente qmailr:qmail
se si è deciso di firmare a livello qmail-remote
, vpopmail:vchkpw
se si è deciso di firmare a livello qmail-smtpd
.
mkdir /usr/local/etc/domainkeys chown -R qmailr:qmail /usr/local/etc/domainkeys chmod -R 700 /usr/local/etc/domainkeys
Usage: /usr/local/bin/domainkey [-p] domain [selector] Create domainkey Print domainkey with -p
Lo script può essere usato per creare la chiave o anche per stampare a video la chiave esistente usando l'opzione -p.
Quando si crea una chiave per un dominio.net essa verrà salvata nella cartella /usr/local/etc/domainkeys/dominio.net. La cartella dovrà appartenere all'utente qmailr (l'utente sotto cui viene eseguito qmail-remote), se si opta per firmare i messaggi in uscita a livello qmail-remote, oppure a vpopmail, che è l'utente sotto cui gira qmail-smtpd, se si opta per firmare i messaggi a livello qmail-smtpd. Come opzione predefinita il mio script attribuisce i privilegi a qmailr.
# domainkey dominio.net Generating RSA private key, 1024 bit long modulus ......................++++++ ........++++++ e is 65537 (0x10001) writing RSA key TXT record for BIND: default._domainkey.dominio.tld. IN TXT ("v=DKIM1; k=rsa; t=y; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwCruZDlA+nSyMO7P5BI1V+ZAmgHSeaZ+XKMiu+s8SZADL4W0X+rhESjeVAkDxMpVapd00EwJ+F7WRVJG5ttoUSjYh9s1JGJ6SG2HgYahrs2hjdpJGsGK3eH4nojirepq/Fx69APsmJOfp6hPi3meyCNBEaVBk88rfBiVzsZHnVKHfK9VbgQ8vBFcnwYl" "LMQXWZedrJ9pc+cofQL8lWPNiXIsvPOLnW3Dou/7XeOiQja/ec0xJMPBkyf6im1zR6AY/wttIDi6k68e+gS9G5YCx4rnI6MF5Qi6bVn+jyaH8HoFAi0JxTt9RCORPshS88BRdDJzzSLEJVZbwSnWES8WfQIDAQAB")
Questo è il record TXT da inserire in un server DNS. Se il tuo Name Server non è bind,
google può sicuramente essere d'aiuto.
Ricordarsi di cancellare il tag t=y (modalità testing attiva) una volta terminata la fase di test.
qmail-remote
per la firma e di qmail-smtpd
per la verifica dei messaggiRiferimenti:
spawn-filter
dk-filter
Ecco come modificare il proprio script /var/qmail/rc
affichè qmail-remote
firmi in uscita i messaggi.
Innanzitutto salvare nel file control/dkimdomain
il dominio che si vuole usare per la firma dei messaggi di sistema senza mittente (null sender "<>"). Questi messaggi di sistema sono dei "rimbalzi" inviati dal nostro server che devono essere firmati pena il loro rigetto proprio a seguito della mancanza della firma (filtro DKIM
e DMARC
).
echo "yourdomain.tld" > /var/qmail/control/dkimdomain
File /var/qmail/rc
#!/bin/sh # Using stdout for logging # Using control/defaultdelivery from qmail-local to deliver messages by default # default domain for null ("<>") sender msg DKIMDOMAIN=`cat /var/qmail/control/dkimdomain` # declaring NODK disables domainkey # declaring NODKIM disables DKIM # DKIM 2048 key sign exec env - PATH="/var/qmail/bin:$PATH" \ QMAILREMOTE=/var/qmail/bin/spawn-filter \ DKIMSIGNOPTIONS="-z 2" \ DKIMDOMAIN="$DKIMDOMAIN" \ NODK=1 \ FILTERARGS=/var/qmail/bin/dk-filter \ qmail-start "`cat /var/qmail/control/defaultdelivery`" # DKIM 1024 key sign #exec env - PATH="/var/qmail/bin:$PATH" \ #QMAILREMOTE=/var/qmail/bin/spawn-filter \ #DKIMDOMAIN="$DKIMDOMAIN" \ #NODK=1 \ #FILTERARGS=/var/qmail/bin/dk-filter \ #qmail-start "`cat /var/qmail/control/defaultdelivery`" # Use this if you don't want to sign or if you're signing at qmail-smtpd level #exec env - PATH="/var/qmail/bin:$PATH" \ #qmail-start "`cat /var/qmail/control/defaultdelivery`"
La variabile QMAILREMOTE fa sì che qmail
chiami spawn-filter
prima che il messaggio sia collocato in coda, il quale a sua volta eseguirà un filtro a scelta dichiarato attraverso la variabile FILTERARGS. Per un controllo più preciso a livello di singoli domini si può usare il control file filterargs
(man spawn-filter
). Inoltre si può usare QMAILLOCAL per firmare anche le email spedite agli utenti del vostro server stesso.
dk-filter
utilizzerà come come locazione della domainkey il file /var/qmail/control/domainkeys/%/default
. Il simbolo '%' verrà automaticamente sostituito con il dominio del mittente. Naturalmente si potrà decidere di firmare tutti domini con un singola firma collocata in /var/qmail/control/domainkeys/default
Se si ha necessità di salvare la propria chiave altrove, oppure con un nome diverso da default
si può definire la variabile DKIMSIGN
come segue, ponendo questa riga prima del comando qmail-start
DKIMSIGN=/usr/local/etc/domainkeys/example.net/your_keyname
Inserire le seguenti variabili di ambiente nel proprio run file /var/qmail/supervise/qmail-smtpd/run
:
export QMAILQUEUE=/var/qmail/bin/qmail-dkim export DKIMVERIFY="FGHKLMNOQRTVWp" # This is to allow msg without "subject" in the h= list # export UNSIGNED_SUBJECT=1 # This is to avoid verification of outgoing messages export RELAYCLIENT_NODKIMVERIFY=1
Dichiarando UNSIGNED_SUBJECT si possono ammettere le email di alcuni providers che non firmano il subject (maggiori informazioni qui). Ciò però consentirebbe a uno spammer di modificare il subject senza invalidare per questo la firma, quindi usare questa opzione a proprio rischio (io l'ho dovuta abilitare per non rigettare i messaggi provenienti da libero.it).
Dichiarando RELAYCLIENT_NODKIMVERIFY si evita che qmail-dkim
verifichi i propri messaggi in uscita.
Per scegliere al meglio le opzioni per la verifica dei messaggi leggere la pagina man di qmail-dkim
.
Creare un messaggio di test da usare nei test qui sotto (è importante uscire con ctrl+d e che la prima linea non sia vuota):
# cat > /tmp/testmail.txt To: someone@somewhere.xy From: postmaster@yourdomain.xy Subject: DKIM Test Message Test message FOLLOWING A BLANK LINE cntrl-D
Faremo il test come qmailr, l'utente che esegue qmail-remote e che ha i privilegi di lettura della domainkey.
# su qmailr # declare -x QMAILREMOTE=/var/qmail/bin/spawn-filter # declare -x DKIMSIGNOPTIONS="-z 2" # only if 2048 key sign # declare -x _SENDER=postmaster@yourdomain.xy # /var/qmail/bin/dk-filter < /tmp/testmail.txt DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=yourdomain.xy; s=default; h=To:From:Subject; bh=lrIChgTwMnmPKfGEgElIyJgL9jk=; b=LQPayl6VbbITdGjVC6vx2+bYF27jAjAkR6qm967GMd1L+0hb7szwP9cDfvy738 Y05llEnOqMrc1QbGGE9uLxqGQrkOAPhl0q+Hxt8yQz1B4BsVk8vED812K/178pIe f+4oGrnodNCCJwg97TLXJmVdecGbrmOVPiBfm51kl4nSI= To: someone@somewhere.xy From: postmaster@yourdomain.xy Subject: DKIM Test Tessage Test message FOLLOWING A BLANK LINE
Mandare un messaggio a sè stessi a guardare la firma DKIM nell'header:
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=yourdomain.xy; s=private; x=1298156019; h=to:from:subject; bh=tVrwKZaEzYO4qmI9mPfR04ZvZik=; b=r2VH/6rQdY6xcPjyg55ULnf7U+DEs +apecicwvygIZVvQwxU4NqiqAQGTF3Qkft2eBDu42TBzX4nV7FTs8wzn40iGkfhB mMZhQdcyOseg7DyOFKUK5D8Ji3ueF/xgYFUnffrxPdZUMpGN9+dA9fY0wkonp5ML dDSaNje9mmd34I=
Assumerò qui che vpopmail
sia l'utente che esegue qmail-smtpd
.
# su vpopmail # declare -x DKIMQUEUE=/bin/cat # unset RELAYCLIENT # /var/qmail/bin/qmail-dkim < /tmp/testmail.txt DKIM-Status: no signatures To: someone@somewhere.net From: postmaster@yourdomain.xy Subject: DKIM Test Message Test message FOLLOWING A BLANK LINE
Mandare un messaggio a sè stessi ad esempio da un account gmail.com (che ha la firma DKIM) e controllare l'header. Il messaggio è stato verificato se si ha questa linea nell'header:
DKIM-Status: good
Ecco come testare la firma di un messaggio che è stato preventivamente salvato su disco come email.txt (non creare il file come cut&paste per evitare spazi bianchi accidentali che compremetterebbero la validazione del body, salvare su disco alla maniera normale):
> /var/qmail/bin/dkim -vS < /path/to/email.txt DKIM-Status: good
Infine, inviare una mail a check-auth@verifier.port25.com con "test" come oggetto. Vi risponderanno con un messaggio che conterrà i risultati del test e così saprete se la configurazione del vostro DNS è corretta.
E' anche possibile controllare se il proprio record dns è scritto in modo corretto attraverso questa pagina https://mxtoolbox.com/dkim.aspx.
qmail-dkim
e simscan
vivano insieme felici[Se simscan
non è ancora stato installato si può saltare questo passaggio. qmail
non funzionerà con le direttive seguenti senza simscan
]
Come certamente saprai, anche simscan
ha bisogno di chiamare qmail-queue
e deve essere anche lui incluso nella variabile di ambiente QMAILQUEUE
, proprio come qmail-dkim. Lo stesso dovrebbe succedere con altri scanner per l'email..
Si può risolvere il problema assegnando qmail-dkim
a QMAILQUEUE
e simscan
alla variabile DKIMQUEUE
. In questo caso qmail-dkim
chiamerà simscan
quando avrà finito il suo lavoro.
Per far ciò è necessario modificare come seguee lo script di avvio di qmail-smtpd
/var/qmail/supervise/qmail-smtpd/run
(ed eventualmente anche /var/qmail/supervise/qmail-submission/run
)
export QMAILQUEUE=/var/qmail/bin/qmail-dkim export DKIMQUEUE=/var/qmail/bin/simscan
qmail-smtpd
for signing outgoing messagesSi salti questo paragrafo se si è deciso di apportare la firma attraverso qmail-remote
.
qmail-smtpd
run scriptInnanzitutto salvare nel file control/dkimdomain
il dominio che si vuole usare per la firma dei messaggi di sistema senza mittente (null sender "<>"). Questi messaggi di sistema sono dei "rimbalzi" inviati dal nostro server che devono essere firmati pena il loro rigetto proprio a seguito della mancanza della firma (filtro DKIM
e DMARC
).
echo "yourdomain.tld" > /var/qmail/control/dkimdomain
Inserire le seguenti variabili d'ambiente nel proprio /var/qmail/supervise/qmail-smtpd/run
script:
DKIMDOMAIN=`cat /var/qmail/control/dkimdomain` export QMAILQUEUE=/var/qmail/bin/qmail-dkim export DKIMKEY=/usr/local/etc/domainkeys/%/default export DKIMDOMAIN="$DKIMDOMAIN" # declaring NODK disables domainkey # declaring NODKIM disables DKIM export NODK=1
qmail-dkim
firmerà i messaggi se la variabile RELAYCLIENT è stata impostata (guardare il file tcp.smtp
) ed eseguirà la verifica in tutti i messaggi degli IP per cui quali RELAYCLIENT non è stata impostata.
DKIMKEY è la posizione della chiave. Il simbolo '%' verrà automaticamente sostituito con is con il dominio del mittente. Naturalmente si può decidere di firmare tutti i domini con una singola chiave collocata in /usr/local/etc/domainkeys/default
.
# cat > /tmp/testmail.txt To: someone@somewhere.xyz From: postmaster@yourdomain.xyz Subject: Test Message Test message FOLLOWING A BLANK LINE THAT YOU DON'T HAVE TO FORGET cntrl-D
In this test qmail-dkim assumes that the domainkey is stored in the /var/qmail/control/domainkeys folder, so if your domainkeys are stored elsewhere create a symbolic link.
# su vpopmail # declare -x DKIMQUEUE=/bin/cat # declare -x DKIMKEY=/var/qmail/control/domainkeys/%/default # declare -x RELAYCLIENT="" # /var/qmail/bin/qmail-dkim < /tmp/testmail.txt DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=yourdomain.xyz; s=default; x=1298483339; h=To:From:Subject; bh=6rJdFs2WVS8T72i61KhaAvC6O6s=; b=ffnXBB98Gg6iZFEIL6alk8c5davso ozyrunXM3C8qaejIrJOwYhnlWQwSdrV599WErmJcDYyMjFjVgLzRQ9OTeYHjEnHT X/aiIkvjcxRuOaTK7PcwrcJGdtF0c6LWoK9RgiPctCw7DMcHGmUcSyXWc6ayzHgX A7nopQYuHzTuIU= To: someone@somewhere.xyz From: postmaster@yourdomain.xyz Subject: Test Message Test message FOLLOWING A BLANK LINE THAT YOU DON'T HAVE TO FORGET
If RELAYCLIENT is defined and both DKIMSIGN and DKIMVERIFY are not defined then qmail-dkim looks for DKIMKEY for the private key to sign. If DKIMKEY is not defined, then control/domainkeys/%/default is used
If RELAYCLIENT is not defined, then qmail-dkim uses DKIMSIGN for the key
If the key has % in the filename, then it is replaced with the domain name from the From/Sender header. After substituting %, if the private key is not found, the qmail-dkim removes the % and again checks for the key. e.g. strace shows this
access("control/domainkeys/mydomain.org/default", F_OK) = -1 ENOENT (No such file or directory) open("control/domainkeys/default", O_RDONLY|O_NONBLOCK) = 5
If the key has % in the filename and the private key does not exists, then qmail-dkim exits without signing and without any failure. Hence messages will pass through. The reason for this behaviour is i have many clients who run multiple domains on a server and they need DKIM only for few domains.
If the key does not have % sign and the private key does not exist, then qmail-dkim exits with 32 resulting in permanent failure
"Private key file does not exist (#5.3.5)"
If none of the variables RELAYCLIENT, DKIMSIGN, DKIMVERIFY are defined, qmail-dkim does verification
IndiMailfilter command is missing?
28 giugno 2022 12:42
IndiMailfilter command is missing?
28 giugno 2022 11:31
IndiMailfilter command is missing?
20 giugno 2022 13:23
"IndiMailfilter" command is missing?
20 giugno 2022 13:01
"IndiMailfilter" command is missing?
20 giugno 2022 11:31
fehQlibs *.so is not installed by "make install"
11 giugno 2022 02:44
Missing suid and sgid
8 giugno 2022 12:31
Missing suid and sgid
8 giugno 2022 10:42
incoming maximum number of recipients allowed
31 maggio 2022 09:04
incoming maximum number of recipients allowed
31 maggio 2022 04:53
Tags
apache clamav dkim dovecot ezmlm fail2ban ftp guide hacks lamp letsencrypt linux linux-vserver lxc mariadb mediawiki mozilla mysql openboard owncloud patches php proftpd qmail qmail-spp qmailadmin rbl roundcube rsync sieve simscan slackware solr spamassassin spf ssh ssl tcprules tex ucspi-tcp vpopmail vqadmin
Commenti
domainkeys valore di t
Adele 16 giugno 2018 18:49
Ciao Roberto,
per un server in produzione devo cambiare il valore "t" da "y" nei TXT records a "n" oppure lo posso lasciare come lo genera lo script? Forse mi conviene modifcare lo script dato che faccio copia e incolla! :-)
Bellissima guida.
Grazie.Adele
Rispondi | Permalink
domainkeys valore di t
Roberto Puzzanghera Adele 16 giugno 2018 19:46
Ciao Adele, potresti anche togliere del tutto il campo t=y
Rispondi | Permalink
Cambio da rsa-sha1 a rsa-sha256 per dkim
malvivent7 19 gennaio 2015 21:20
Ottima guida, volevo chiedre come poter cambiare la versione dell'hash di firma per dkim da rsa-sha1 a rsa-sha256 in quanto piu' sicura
Rispondi | Permalink
Credo che dovresti editare lo
roberto puzzanghera malvivent7 19 gennaio 2015 21:59
Credo che dovresti editare lo script e settare appositamente openssl, vedi il man. Fammi sapere....
Rispondi | Permalink