DKIM-DMARC-SPF » Cronologia » Versione 2
Simone Piccardi, 12-08-2016 15:23
1 | 1 | Simone Piccardi | h1. Installazione di DKIM/DMARC/SPF & C |
---|---|---|---|
2 | |||
3 | 2 | Simone Piccardi | Per gestire la posta in uscita per SPF non occorre fare altro che creare il relativo record TXT sul proprio dominio, se però si vuole verificare la validità della posta in ingresso e prendere eventuali provvedimenti, occorrerà installare (dal pacchetto omonimo) e configurare @postfix-policyd-spf-python@. |
4 | 1 | Simone Piccardi | |
5 | 2 | Simone Piccardi | Il file di configurazione è @/etc/postfix-policyd-spf-python/policyd-spf.conf@, in cui inserire un contenuto del tipo: |
6 | 1 | Simone Piccardi | |
7 | <pre> |
||
8 | #HELO_reject = SPF_Not_Pass |
||
9 | #Mail_From_reject = Fail |
||
10 | HELO_reject = False |
||
11 | Mail_From_reject = False |
||
12 | |||
13 | Authserv_Id = holland |
||
14 | Header_Type = SPF |
||
15 | </pre> |
||
16 | |||
17 | 2 | Simone Piccardi | in cui di commentano le istruzioni che farebbero respingere la posta, si indica la macchina che esegue i controlli (indicando l'hostname con @Authserv_Id@) e si indica con @Header_Type@ di inserire un header coi risultati di autenticazione. Le due possibilità sono @AR@ e @SPF@, il primo sarebbe lo standard preferito da @opendmarc@, ma non funziona. |
18 | 1 | Simone Piccardi | |
19 | 2 | Simone Piccardi | Occorre poi configurare postfix per usare il programma come policy service, pertanto si dovrà prima configurarne l'avvio in @master.cf@ aggiungendo le righe: |
20 | 1 | Simone Piccardi | |
21 | <pre> |
||
22 | # for SPF check |
||
23 | policyd-spf unix - n n - 0 spawn |
||
24 | user=nobody argv=/usr/bin/python /usr/bin/policyd-spf /etc/postfix-policyd-spf |
||
25 | -python/policyd-spf.conf |
||
26 | </pre> |
||
27 | |||
28 | e poi abilitarne l'uso in @main.cf@ con: |
||
29 | |||
30 | <pre> |
||
31 | smtpd_recipient_restrictions = |
||
32 | ... |
||
33 | reject_unauth_destination, |
||
34 | check_policy_service unix:private/policyd-spf, |
||
35 | ... |
||
36 | |||
37 | policyd-spf_time_limit = 3600 |
||
38 | </pre> |
||
39 | |||
40 | Per Debian Wheezy. Installare OpenDKIM: |
||
41 | |||
42 | <pre> |
||
43 | apt-get install opendkim opendkim-tools |
||
44 | </pre> |
||
45 | |||
46 | modificare il file di configurazione @/etc/opendkim.conf@ aggiungendo: |
||
47 | |||
48 | <pre> |
||
49 | ## Added configurations |
||
50 | |||
51 | KeyTable /etc/opendkim/key_table |
||
52 | SigningTable /etc/opendkim/signing_table |
||
53 | ExternalIgnoreList /etc/opendkim/trusted_hosts |
||
54 | InternalHosts /etc/opendkim/trusted_hosts |
||
55 | AutoRestart Yes |
||
56 | AutoRestartRate 10/1h |
||
57 | Mode sv |
||
58 | PidFile /var/run/opendkim/opendkim.pid |
||
59 | SignatureAlgorithm rsa-sha256 |
||
60 | Canonicalization relaxed/simple |
||
61 | UserID opendkim:opendkim |
||
62 | |||
63 | # Added to write headers |
||
64 | AuthservID HOSTNAME |
||
65 | </pre> |
||
66 | |||
67 | 2 | Simone Piccardi | Dove l'ultima riga è essenziale se si vuole che @opendkim@ controllando le firme dei messaggi in arrivo costruisca un corretto header di autenticazione ad uso sia di @opendmarc@ che del debug dei relativi problemi, la parola chiave @HOSTNAME@ assegna un identificativo di chi ha eseguito il controllo automaticamente inizializzato all'hostname della macchina su cui lo si esegue. |
68 | 1 | Simone Piccardi | |
69 | 2 | Simone Piccardi | Occorre poi creare la directory @/etc/opendkim/@ ed una sottodirectory per ciascun dominio che si vuole utilizzare: |
70 | 1 | Simone Piccardi | |
71 | <pre> |
||
72 | mkdir /etc/opendkim |
||
73 | mkdir /etc/opendkim/truelite.it |
||
74 | mkdir /etc/opendkim/fountainpen.it |
||
75 | ... |
||
76 | </pre> |
||
77 | |||
78 | per ciascun dominio creare una chiave RSA con: |
||
79 | |||
80 | <pre> |
||
81 | cd /etc/opendkim/truelite.it |
||
82 | opendkim-genkey -b 2048 -s mail -d truelite.it |
||
83 | </pre> |
||
84 | |||
85 | 2 | Simone Piccardi | oppure, se non si è paranoici e ci si accontenta della sicurezza standard che nel caso, non avendo da cifrare dati ma solo da inserire un token di reputazione per la firma è senz'altro sufficiente: |
86 | 1 | Simone Piccardi | |
87 | <pre> |
||
88 | opendkim-genkey -s mail -d truelite.it |
||
89 | </pre> |
||
90 | |||
91 | 2 | Simone Piccardi | che genera una chiave RSA da 1024 bit, che comunque é la dimensione raccomandata dalle specifiche di DKIM e che è anche più semplice da |
92 | gestire con il DNS. (occorre verificare se si può usare la stessa chiave per più domini) |
||
93 | 1 | Simone Piccardi | |
94 | 2 | Simone Piccardi | Questo crea due file usando come nome il selettore (l'argomento dell'opzione @-s@), nel caso @mail.private@ con la chiave privata e |
95 | @mail.txt@ che contiene il record TXT da aggiungere al DNS (ma questo fa fatto solo dopo aver verificato che la firma con DKIM funziona) con |
||
96 | la chiave pubblica. |
||
97 | 1 | Simone Piccardi | |
98 | 2 | Simone Piccardi | Si tenga conto che con la configurazione precedente opendkim viene eseguito con un utente non privilegiato, per cui occorrerà cambiare il permesso della chiave privata con: |
99 | 1 | Simone Piccardi | |
100 | <pre> |
||
101 | chown opendkim mail.private |
||
102 | </pre> |
||
103 | |||
104 | 2 | Simone Piccardi | Occorre poi inserire in @/etc/opendkim/trusted_host@ la lista degli IP/host/reti che si considerano fidate sia per la ricezione, che per la spedizione, in particolare usando questa lista con @ExternalIgnoreList@ si dice a OpenDKIM di ignorarle nella verifica delle email in ingresso, mentre con @InternalHosts@ si dice che la posta che arriva da detti IP deve essere firmata. |
105 | 1 | Simone Piccardi | |
106 | 2 | Simone Piccardi | Occorre fare attenzione in particolare a @InternalHosts@ in quanto se non si indica nulla viene abilitata comunque la firma delle email inviata passando dal @localhost@ (o meglio da @127.0.0.1@, se come su Debian @localhost@ risolve in IPv6 su @::1@ l'invio di email fatto con connessioni a @localhost@ non sarà firmato) ma se si indica un file, questo default sparisce e 127.0.0.1 deve essere esplicitamente inserito nel file. Un esempio è il seguente: |
107 | 1 | Simone Piccardi | |
108 | <pre> |
||
109 | # localhost |
||
110 | 127.0.0.1 |
||
111 | ::1 |
||
112 | localhost |
||
113 | # other hosts |
||
114 | holland.truelite.it |
||
115 | 144.76.13.157 |
||
116 | 144.76.13.137 |
||
117 | 136.243.5.189 |
||
118 | 136.243.5.190 |
||
119 | 136.243.5.137 |
||
120 | # local subnet |
||
121 | 192.168.1.0/24 |
||
122 | </pre> |
||
123 | |||
124 | 2 | Simone Piccardi | Avendola dichiarata in @KeyTable@ occorre inserire nel file @/etc/opendkim/key_table@ la tabella che indicizza le chiavi da utilizzare; la tabella è realizzata con due campi testuali separati da uno spazio. |
125 | 1 | Simone Piccardi | |
126 | 2 | Simone Piccardi | Il primo campo è la chiave di indicizzazione e può essere una stringa qualsiasi (nel caso si è deciso di usare, per essere univoci, il nome del record TXT che metteremo nel DNS, ma poteva anche essere qualunque cosa). |
127 | 1 | Simone Piccardi | |
128 | 2 | Simone Piccardi | Il secondo campo è il valore associato alla chiave che indica come effettuare la firma, e prevede tre valori che vanno scritti di seguito separati dal carattere ":" e senza spazi. Il primo valore indica il dominio che si vuole sia inserito nella firma (quello indicato come argomento di @-d2 quando si è creata la chiave), il secondo indica il selettore (quello usato come argomento di @-s@ quando si è creata la chiave), ed il terzo il file (con il pathname assoluto, per semplicità) contenente la chiave privata con cui eseguire la firma; nel nostro caso si è usato (corripondendo ai parametri usati nel creare la chiave): |
129 | 1 | Simone Piccardi | |
130 | <pre> |
||
131 | mail._domainkey.truelite.it truelite.it:mail:/etc/opendkim/truelite.it/mail.private |
||
132 | mail._domainkey.truelite.eu truelite.eu:mail:/etc/opendkim/truelite.it/mail.private |
||
133 | </pre> |
||
134 | |||
135 | ma poteva anche essere qualcosa del tipo: |
||
136 | |||
137 | <pre> |
||
138 | pinco truelite.it:mail:/etc/opendkim/truelite.it/mail.private |
||
139 | pluto truelite.eu:mail:/etc/opendkim/truelite.it/mail.private |
||
140 | </pre> |
||
141 | |||
142 | 2 | Simone Piccardi | La firma dei messaggi in uscita è controllata, avendolo impostato con @SigningTable@, dal contenuto del @/etc/opendkim/signing_table@, il file |
143 | contiene la tabella, con due campi separati da spaziature delle corrispondenze che consentono di selezionare, sulla base dell'indirizzo di posta del mittente, quale chiave crittografica usare per la firma, da indicare con l'etichetta usata in @/etc/opendkim/key_table@. |
||
144 | 1 | Simone Piccardi | |
145 | 2 | Simone Piccardi | Se si usa come nell'esempio un file ordinario il valore campo from viene confrontato con la chiave (il primo campo di @/etc/opendkim/signing_table@) e se viene trovata una corrispondenza, la email viene firmata con la chiave crittografica indicata dal secondo campo (usata come indice in @/etc/opendkim/key_table@). La corrispondenza deve essere esatta, ma viene cercata prima sul mittente completo, e poi sul dominio (e poi per il mittente su eventuali sottodomini). |
146 | 1 | Simone Piccardi | |
147 | 2 | Simone Piccardi | Di default, a meno di non aver abilitato firme multiple, l'esame del file si ferma alla prima corrispondenza. Nel nostro caso si è usato: |
148 | 1 | Simone Piccardi | |
149 | <pre> |
||
150 | truelite.it mail._domainkey.truelite.it |
||
151 | truelite.eu mail._domainkey.truelite.eu |
||
152 | </pre> |
||
153 | |||
154 | 2 | Simone Piccardi | Se serve una corripondenza più complessa si può indicare nella configurazione di @opendkim.conf@ il file come: |
155 | 1 | Simone Piccardi | |
156 | <pre> |
||
157 | SigningTable refile:/etc/opendkim/signing_table |
||
158 | </pre> |
||
159 | |||
160 | 2 | Simone Piccardi | ed in tal caso la chiave viene usata come pattern in cui si può usare un "*" come carattere jolly. |
161 | 1 | Simone Piccardi | |
162 | 2 | Simone Piccardi | Una volta configurati i vari domini, le relative chiavi, e le modalità del relativo uso nella firma, si potrà avviare il servizio. Nel nostro caso si è preferito per semplicità, farlo ascoltare su un socket su localhost, questo si fa scommentando la seguente riga in @/etc/default/opendkim@: |
163 | 1 | Simone Piccardi | |
164 | <pre> |
||
165 | SOCKET="inet:12345@localhost" # listen on loopback on port 12345 |
||
166 | </pre> |
||
167 | |||
168 | 2 | Simone Piccardi | è possibile anche usare un socket locale, che però andrà creato nel chroot di postfix (ad esempio in @/var/spool/postfix/private/opendkim@) e con permessi adeguati a far si che postfix possa operarvi. Si ricordi di riavviare il servizio con: |
169 | 1 | Simone Piccardi | |
170 | <pre> |
||
171 | service opendkim restart |
||
172 | </pre> |
||
173 | |||
174 | 2 | Simone Piccardi | Per poter usare il servizio di OpenDKIM da postfix occorre configurarne l'uso come milter, aggiungendo a @/etc/postfix/main.cf@ le seguenti righe: |
175 | 1 | Simone Piccardi | |
176 | <pre> |
||
177 | # DKIM/DMARK addition |
||
178 | milter_protocol = 6 |
||
179 | milter_default_action = accept |
||
180 | smtpd_milters = inet:localhost:12345 |
||
181 | non_smtpd_milters = inet:localhost:12345 |
||
182 | </pre> |
||
183 | |||
184 | 2 | Simone Piccardi | e conviene inoltre modificare la configurazione di @amavis-new@ in @/etc/postfix/master.cf@ aggiungendo: |
185 | 1 | Simone Piccardi | |
186 | <pre> |
||
187 | 127.0.0.1:10025 inet n - y - - smtpd |
||
188 | -o content_filter= |
||
189 | ... |
||
190 | -o smtpd_hard_error_limit=1000 |
||
191 | -o smtpd_milters= |
||
192 | </pre> |
||
193 | |||
194 | per evitare di fagli eseguire due volte il filtro. |
||
195 | |||
196 | 2 | Simone Piccardi | A questo punto si potrà riavviare Postfix e verificare, inviando una email, che questa sia correttamente firmata, riportando negli header qualcosa del tipo: |
197 | 1 | Simone Piccardi | |
198 | <pre> |
||
199 | DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=truelite.it; s=mail; |
||
200 | t=1449592614; bh=73owTq/o58W9zoPsclFWibqVtDP8ZlpL+oASguLeSqM=; |
||
201 | h=To:From:Subject:Date:From; |
||
202 | b=QwEiNmvmmTGuwI+0j5Z9Too4jnAwswQ2orR1mcOoRGapCP3Tc8FSftzJm9Y0i4HR+ |
||
203 | DpQJJXfEHPuB20hohsMm1ttMyoyokqPxoAMSuC/pnzkITjgn+/RZH1nqpeRKwvnTKC |
||
204 | OBQOewHKiH5DnPyEIIqv3ATKn9CTb04DlFCpwHfXe97xLZm0n69DS9YFSJtVxtMCEa |
||
205 | 5S67bV8kELwuOGqXK7GJ3KvWdMmYcEmubdgIOOnrbjn61lMztXLdifatDMKw1YZblp |
||
206 | b5WRAhHHYe222lCimLE6CS2RF6+82jeqqgUHrq3WLNRYlvhc7qG/MlqVqZC1qzxMmy |
||
207 | 32uYD888clI4A== |
||
208 | </pre> |
||
209 | |||
210 | 2 | Simone Piccardi | Il passo finale per completare la configurazione di DKIM è impostare il DNS per pubblicare la propria chiave. Il record da inserire nel proprio dominio è direttamente disponibile nel file @mail.txt@, ma inserire direttamente il contenuto di questo file in un file di zona darà luogo ad errore in quanto la stringa di testo che indica la chiave è più lunga (per chiavi di 2048 bit come quella utilizzata) del massimo di 256 caratteri supportati da @bind@, questo si può risolvere spezzando la stringa, pertanto si dovrà inserire nel file di zona qualcosa del tipo (questo non serve per le dimensioni di default di una chiave a 1024 bit, che possono essere inserite direttamente): |
211 | 1 | Simone Piccardi | |
212 | <pre> |
||
213 | mail._domainkey IN TXT ( |
||
214 | "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2MfnM" |
||
215 | "zbBCutJTkkZQe+5kAZlls5MZzsSzRVMtOn/FS6fS14wB0+Qn+SIXbewZxcg/37+iJ/" |
||
216 | "qiOe5Xf7GF4IzvVSlXKswLVtiLdZU//0Dkq5YByL9pEQwtgsEJOnV+cHUEyjDRfoFk" |
||
217 | "Qp0GdZXw/V42Pa7RzIAGFlJAPRAwCrEOYcMCPvu243PLjUhjV8Dl79EEipaZKLAAdyK" |
||
218 | "2XsyDOGTTuBHiQ5Y06IV7BTi9cS76limReZcAGUBds/cwRvzZNhnq8V+sEEe05p0TrD" |
||
219 | "0HcPwDCLT7M6tvb8q+1KDqBQzZF5xtILOPiEYFUEaBuBSkh2BNTQaa8UnlYnXUjJ5Ed" |
||
220 | "Q5AQIDAQAB" ) |
||
221 | </pre> |
||
222 | |||
223 | per verificare la firma si installi: |
||
224 | |||
225 | <pre> |
||
226 | apt-get install python-dkim |
||
227 | </pre> |
||
228 | |||
229 | e poi si potrà effettuare la verifica con: |
||
230 | |||
231 | <pre> |
||
232 | dkimverify < /path/to/email/message |
||
233 | </pre> |
||
234 | |||
235 | 2 | Simone Piccardi | Come passo ulteriore si può installare OpenDMARC per abilitare la verifica di DMARC su postfix, ma serve solo per la ricezione, per cui se non si intende usarlo, si può saltare questa parte. Per Wheezy il pacchetto è disponibile nei backports, e si installa con: |
236 | 1 | Simone Piccardi | |
237 | <pre> |
||
238 | apt-get install -t wheezy-backports install opendmarc |
||
239 | </pre> |
||
240 | |||
241 | per la configurazione si aggiunga a @/etc/opendmark.conf@ le seguenti righe: |
||
242 | |||
243 | <pre> |
||
244 | ## |
||
245 | ## Added values |
||
246 | ## |
||
247 | AuthservID HOSTNAME |
||
248 | TrustedAuthservIDs HOSTNAME |
||
249 | #TrustedAuthservIDs jojo.truelite.it holland.truelite.it |
||
250 | IgnoreHosts /etc/opendmarc/ignore.hosts |
||
251 | HistoryFile /var/run/opendmarc/opendmarc.dat |
||
252 | # for test |
||
253 | SoftwareHeader true |
||
254 | </pre> |
||
255 | |||
256 | 2 | Simone Piccardi | nel file @/etc/opendmarc/ignore.hosts@ va messo l'elenco delle macchine per le quali non si vuole effettuare il controllo della posta ricevuta con DMARC. Questo vale per il server stesso (ed infatti in genere vi si mette il @localhost@) ma anche per le reti locali del @mynetworks@ di Postfix, che in genere non vengono elencate nei record di SPF. In questo modo si evita che il server, pur spedendo correttamente verso l'esterno, classifiche le email provenienti dai suddetti indirizzi come @fail@ per DMARC quando le controlla. Un esempio del file è il seguente: |
257 | 1 | Simone Piccardi | |
258 | <pre> |
||
259 | # localhost |
||
260 | 127.0.0.1 |
||
261 | holland.truelite.it |
||
262 | 192.168.2.0/24 |
||
263 | 192.168.1.0/24 |
||
264 | |||
265 | # other hosts |
||
266 | jojo.truelite.it |
||
267 | </pre> |
||
268 | |||
269 | 2 | Simone Piccardi | Invece in @/var/run/opendmarc/opendmarc.dat@ verranno salvati i dati dei controlli eventualmente usabili per inviare i rapporti ai mittenti (non ancora configurati). |
270 | 1 | Simone Piccardi | |
271 | 2 | Simone Piccardi | Le configurazioni di @AuthservID@ e @TrustedAuthservIDs@ con @HOSTNAME@ sono necessarie perché il programma possa generare un header con i risultati dell'autenticazione di DMARC. Invece @SPFSelfValidate@ dovrebe richiedergli di controllare il risultato di SPF se non lo trova negli header. |
272 | 1 | Simone Piccardi | |
273 | 2 | Simone Piccardi | Per poter usare il servizio occorrerà attivare l'uso di un socket inserendo in @/etc/default/opendmark@ la riga: |
274 | 1 | Simone Piccardi | |
275 | <pre> |
||
276 | SOCKET="inet:54321@localhost" # listen on loopback on port 12345 |
||
277 | </pre> |
||
278 | |||
279 | e modificare la configurazione di postfix in @/etc/postfix/main.cf@ in: |
||
280 | |||
281 | <pre> |
||
282 | # DKIM/DMARK addition |
||
283 | milter_protocol = 6 |
||
284 | milter_default_action = accept |
||
285 | smtpd_milters = inet:localhost:12345,inet:localhost:54321 |
||
286 | non_smtpd_milters = ${smtpd_milters} |
||
287 | </pre> |
||
288 | |||
289 | ricordandosi di riavviare i servizi: |
||
290 | |||
291 | <pre> |
||
292 | service opendmarc restart |
||
293 | service postfix restart |
||
294 | </pre> |