zkk / VPS email server



Inviare email

Postfix

Come di consueto aggiorno il sistema, apro le porte necessarie per poter inviare le email, installo i pacchetti necesasri e creo un utente normale.

apt update
apt upgrade
ufw allow 25
ufw allow 587
apt install mailutils postfix
useradd -m -s /bin/bash max
passwd max

A questo punto faccio il backup del file di configurazione di postfix (/etc/postfix/main.cf) ed applico una riconfigurazione del pacchetto inserendo quanto riportato in tabella più sotto.

cp /etc/postfix/main.cf /etc/postfix/main.cf.bak
dpkg-reconfigure postfix

Rispondo alle domande come segue:

DomandaRisposta
General email configuration type:Internet Site
System mail name:max73.it
Recipient for root and postmaster mail:max@max73.it
Other destinations to accept mail for (blank for none):mail.max73.it, localhost.max73.it, localhost, max73.it
Force synchronous updates on mail queue?
Local networks:127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
Mailbox size limit (bytes):0
Local address extension charachter:+
Internet protocol to use:all

Le email ricevute vengono aggiunte al file /var/spool/mail/<username>, alternativamente, per avere una cartella all’interno della propria homedirectory con un file per ogni messaggio ricevuto, devo inserisco la seguente riga nel file di configurazione /etc/postfix/main.cf:

echo "home_mailbox = Maildir/" >> /etc/postfix/main.cf

Cosa che possiamo anche evitare di fare in quanto, prima della fine della presente configurazione, installeremo dovecot che gestirà le email all’interno di una cartella situata nella homedirectory chiamata Mail, pertanto alla fine Maildir potrà essere concellata.

Infine riavvio il servizio di posta e provo a madare una email:

systemctl reload postfix
echo "Body." | mail -s "Subject." max@massimo-fontana.net

NB!!! ATTENZONE!!!

Il file /etc/postfix/main.cf contiene alcune righe che fanno riferimento all’invio delle informazioni criptate (TLS). Precisamente le righe sono le seguenti:

# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key

Che vanno sostituite con i riferimenti corretti:

# TLS parameters
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.max73.it/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.max73.it/privkey.pem

Reverse DNS

All’interno del pannello di controllo di Aruba Cloud, nella sezione COMPUTE -> Rete -> IP Pubblici è possibile configurare il Reverse DNS per il mio IP, ovvero la corrispondenza tra IP e dominio, purtroppo solamente per ipv4. Inserisco quindi l’hostname max73.it.

DKIM

E’ uno sctrumento che, tramite la creazione di una coppia di chiavi pubblica/privata, permette di rendere riconoscibile il mio server agli altri che riceveranno i messaggi.

apt install opendkim opendkim-tools
mkdir -p /etc/postfix/dkim
opendkim-genkey -D /etc/postfix/dkim/ -d max73.it -s mail
chgrp opendkim /etc/postfix/dkim/*
chmod g+r /etc/postfix/dkim/*
echo "mail._domainkey.max73.it max73.it:mail:/etc/postfix/dkim/mail.private" > /etc/postfix/dkim/keytable
echo "*@max73.it mail._domainkey.max73.it" > /etc/postfix/dkim/signingtable
echo -e "127.0.0.1\n10.1.0.0/16\n1.2.3.4/24" > /etc/postfix/dkim/trustedhosts

Aggiungo quanto segue alla fine del file /etc/opendkim.conf avendo cura di commentare la riga già presente che inizia con Socket:

KeyTable file:/etc/postfix/dkim/keytable
SigningTable refile:/etc/postfix/dkim/signingtable
InternalHosts refile:/etc/postfix/dkim/trustedhosts
Canonicalization        relaxed/simple
Socket                  inet:12301@localhost

Eseguo i seguenti comandi che aggiungono istruzioni al file di configurazione di postfix, ovvero /etc/postfix/main.cf (fare attenzione che il file /etc/mailname contenga il mio dominio max73.it), altrimenti inserirlo:

echo "massimo-fontana.net" > /etc/mailname
postconf -e "myhostname = $(cat /etc/mailname)"
postconf -e "milter_default_action = accept"
postconf -e "milter_protocol = 6"
postconf -e "smtpd_milters = inet:localhost:12301"
postconf -e "non_smtpd_milters = inet:localhost:12301"
systemctl restart opendkim
systemctl enable opendkim
systemctl reload postfix

Agggiungere i seguenti valori DNS all’interno dell’account di Aruba Cloud alla sezione TXT come segue:

PriorityHostTXT ValueTTL
0mail._domainkeyv=DKIM1; k=rsa; p=(…)300

Alla colonna TXT Value va inserito il contenuto del file /etc/postfix/dkim/mail.txt.

Ora inserisco il valore corretto (quindi max73.it) all’interno del file /etc/hostname e riavvio il server:

echo "max73.it" > /etc/hostname
shutdown -r now

DMARC

Questo è un protocollo necesario per impedire un utilizzo non autorizzato del proprio dominio, serve ancora per evitare spam e farsi accettare dagli altri server di posta quando si spediscono le email, eseguo i seguenti comandi:

useradd -m -G mail dmarc
echo "_dmarc.$(cat /etc/mailname)"
echo "v=DMARC1; p=reject; rua=mailto:dmarc@$(cat /etc/mailname); fo=1"

Utilizzo l’output dei comandi precedenti per inserire i valori che scaturiscono dai comandi echo all’interno di Aruba Cloud DNS nella sezione TXT, dovrebbe essere simile a quanto in tabella:

PriorityHostTXT ValueTTL
0_dmarcv=DMARC1…300

SPF (Sender Policy Framework)

Allo stesso modo che per DKIM e DMARK, SPF previenegli spammer da spedire messaggi che possano apparire inviati dal mio server:

cat /etc/mailname
IP4='my-ipv4'
IP6='my-ipv6'
echo "v=spf1 mx a:mail.$(cat /etc/mailname) ip4:$IP4 ip6:$IP6 -all"

Sempre nella sezione TXT della configurazione dei DNS dell’account Aruba Cloud inserisco il risultato del primo comando (cat) e del comando (echo), che dovrebbe essere come segue:

PriorityHostTXT ValueTTL
<30>
0v=spf1 mx a:mail.max73.it ip4:195.231.80.77 ip6:2a00:6d42:1242:174d::1 -all300

Verifica della configurazione

Al seguente LINK è possibile effettuare un test inviando una email e verificando di avere fatto tutto giusto, ad esempio:

echo "Test dkim." | mail -s "test email." test-da745b6b@appmaildev.com

Allo stesso modo posso inviare una email al mio indirizzo Gmail facendo attenzione che la email il primo invio andrà nello spam:

echo "Test dkim." | mail -s "test email." maxmatty@gmail.com

A questo punto il sistema è in grado di inviare email all’esterno.

Il prossimo passo è ricevere email dall’esterno e permettere ad un utente di leggerle ed inviare a sua volta email all’esterno tramite una interfaccia gradevole ed usabile.

Ricevere email

Dovecot e spamassassin

Installo i pacchetti necessari, apro la porta della posta in arrivo e certifico l’indirizzo del mio mail server:

apt install dovecot-imapd dovecot-sieve spamassassin spamc
ufw allow 993
certbot --nginx certonly -d mail.mx73.it

All’interno della configurazione DNS di Aruba Cloud vado ad aggiungere il sottodominio mail.max73.it nella categoria dei Record A e dei Record AAA (vedi Attivazione DNS sopra) come segue:

HOSTINDIRIZZO IPV4TTL
mail.max73.it195.231.80.77300
HOSTINDIRIZZO IPV6TTL
mail.max73.it2a00:6d42:1242:174d::1300

Aggiungo i seguenti valori all’interno della categoria Record MX:

DOMINIOHOSTPRIORITA'TTL
max73.itmail.max73.it10300

E nella sezione COMPUTE -> Rete -> IP Pubblici inserisco anche l’indirizzo host mail.max73.it per il reverse DNS.

Configurazione dovecot

Faccio il backup del file di configurazione di dovecot e inserisco la seguente configurazione (file /etc/dovecot/dovecot.conf):

# Note that in the dovecot conf, you can use:
# %u for username
# %n for the name in name@domain.tld
# %d for the domain
# %h the user's home directory

# Connections between the mail client and Dovecot needs to be encrypted
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.max73.it/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.max73.it/privkey.pem
ssl_min_protocol = TLSv1.2
ssl_cipher_list = EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA256:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EDH+aRSA+AESGCM:EDH+aRSA+SHA256:EDH+aRSA:EECDH:!aNULL:!eNULL:!MEDIUM:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4:!SEED
ssl_prefer_server_ciphers = yes
ssl_dh = </usr/share/dovecot/dh.pem
auth_mechanisms = plain login
auth_username_format = %n

protocols = $protocols imap

# Search for valid users in /etc/passwd
userdb {
    driver = passwd
}
#Fallback: Use plain old PAM to find user passwords
passdb {
    driver = pam
}

# Our mail for each user will be in ~/Mail, and the inbox will be ~/Mail/Inbox
mail_location = maildir:~/Mail:INBOX=~/Mail/Inbox:LAYOUT=fs
namespace inbox {
    inbox = yes
    mailbox Drafts {
	  special_use = \Drafts
	  auto = subscribe
    }
    mailbox Junk {
	  special_use = \Junk
	  auto = subscribe
	  autoexpunge = 30d
    }
    mailbox Sent {
	  special_use = \Sent
	  auto = subscribe
    }
    mailbox Trash {
	  special_use = \Trash
    }
    mailbox Archive {
	  special_use = \Archive
    }
}

# Here we let Postfix use Dovecot's authetication system.
service auth {
    unix_listener /var/spool/postfix/private/auth {
	  mode = 0660
	  user = postfix
	  group = postfix
    }
}

protocol lda {
    mail_plugins = $mail_plugins sieve
}
protocol lmtp {
    mail_plugins = $mail_plugins sieve
}
plugin {
    sieve = ~/.dovecot.sieve
    sieve_default = /var/lib/dovecot/sieve/default.sieve
    sieve_dir = ~/.sieve
    sieve_global_dir = /var/lib/dovecot/sieve/
}

Aggiungo la seguente configurazione al file /var/lib/dovecot/sieve/default.sieve (che non esiste):

mkdir -p /var/lib/dovecot/sieve/
echo -e "require [\"fileinto\", \"mailbox\"];\nif header :contains \"X-Spam-Flag\" \"YES\"\n        {\n                fileinto \"Junk\";\n        }" > /var/lib/dovecot/sieve/default.sieve

Ora creo l’utente vmail che accederà alle email e processo altri comandi, in particolare i comandi postconf inseriscono ulteriori configurazioni al file /etc/postfix/main.cf:

grep -q '^vmail:' /etc/passwd || useradd vmail
chown -R vmail:vmail /var/lib/dovecot
sievec /var/lib/dovecot/sieve/default.sieve
echo -e "auth    required        pam_unix.so nullok\naccount required        pam_unix.so" >> /etc/pam.d/dovecot
postconf -e 'smtpd_sasl_auth_enable = yes'
postconf -e 'smtpd_sasl_type = dovecot'
postconf -e 'smtpd_sasl_path = private/auth'
postconf -e 'mailbox_command = /usr/lib/dovecot/deliver'

Eseguo il backup di /etc/postfix/master.cf ed eseguo i seguenti ultimi comandi di configurazione:

sed -i '/^\s*-o/d;/^\s*submission/d;/^\s*smtp/d' /etc/postfix/master.cf
echo -e "smtp unix - - n - - smtp\nsmtp inet n - y - - smtpd\n  -o content_filter=spamassassin\nsubmission inet n       -       y       -       -       smtpd\n  -o syslog_name=postfix/submission\n  -o smtpd_tls_security_level=encrypt\n  -o smtpd_sasl_auth_enable=yes\n  -o smtpd_tls_auth_only=yes\nsmtps     inet  n       -       y       -       -       smtpd\n  -o syslog_name=postfix/smtps\n  -o smtpd_tls_wrappermode=yes\n  -o smtpd_sasl_auth_enable=yes\nspamassassin unix -     n       n       -       -       pipe\n  user=debian-spamd argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f \${sender} \${recipient}" >> /etc/postfix/master.cf
usermod -a -G max
postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, reject_unknown_recipient_domain'
echo -e "/^Received:.*/     IGNORE\n/^X-Originating-IP:/    IGNORE\n/^User-Agent:/        IGNORE\n/^X-Mailer:/        IGNORE" >> /etc/postfix/header_checks
postconf -e "header_checks = regexp:/etc/postfix/header_checks"

Fail2ban

E’ un programma che permette di gestire situazioni anomale come qualcuno che cerca di entrare con username e password da un determinato IP.

In questo caso (ad esempio) mette in quarantena per qualche ora tale indirizzo IP.

Installo il relativo pacchetto e creo il file di configurazione local (che ha precedenza su quello con estensione conf):

apt-get install fail2ban
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Nel file /etc/fail2ban/jail.local sostituisco (o aggiungo) i valori delle seguenti sezioni:

[postfix]
enabled  = true
port     = smtp,ssmtp,submission
filter   = postfix
logpath  = /var/log/mail.log

[sasl]
enabled  = true
port     = smtp,ssmtp,submission,imap2,imap3,imaps,pop3,pop3s
filter   = postfix-sasl
# You might consider monitoring /var/log/mail.warn instead if you are
# running postfix since it would provide the same log lines at the
# "warn" level but overall at the smaller filesize.
logpath  = /var/log/mail.warn
maxretry = 1
bantime  = 21600

[dovecot]
enabled = true
port    = smtp,ssmtp,submission,imap2,imap3,imaps,pop3,pop3s
filter  = dovecot
logpath = /var/log/mail.log

Infine riavvio la macchina:

shutdown -r now