---
author: Daniel A. Rodriguez
date: 2021-04-21
---
# Servidor de Correo – Casillas y usuarios virtuales
## Introducción
Este artículo cubre el soporte de múltiples dominios y usuarios virtuales, gestión de alias y correo electrónico mediante interfaces web.
Nombre del Servidor: **servidor.midominio.edu.ar**
Sistema Operativo: **Debian 10 “Buster”**
Instalar paquetes
-----------------
```bash
# apt install postfix postfix-mysql dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-mysql mariadb-server dovecot-sieve dovecot-managesieved
```
Si estás agregando un servidor de correo a un sistema existente algunos paquetes pueden ya estar presentes. Dependiendo de la lista de paquetes previamente instalada, puede que veas o no los avisos para configurar mariadb, postfix, etc. Escoge los valores predeterminados siempre que sea posible.
Configuración de Postfix
------------------------
Esta guía fue creada usando Postfix 3.4.14. Se puede verificar la versión de postfix instalada usando:
```bash
# postconf mail_version
```
La configuración de Postfix tiene 2 archivos importantes: main.cf y master.cf
Vamos a agregar también algunos otros archivos para el sistema virtual de dominio/correo.
### Postfix – master.cf
Para que smtp ‘escuche’ en el puerto 465 (con SSL) y en el puerto 587 (con TLS), es necesario descomentar las siguientes lineas en `master.cf`
```bash
submission inet n - - - - smtpd
smtps inet n - - - - smtpd
```
Se recomienda hacer esto ya que la mayoría de los ISP bloquea el puerto 25 para prevenir spam.
### Diffie – Hellman
El intercambio de claves Diffie-Hellman es un método de intercambio seguro de claves criptográficas a través de un canal público. Su objetivo principal es desarrollar de forma segura secretos compartidos que puedan utilizarse para derivar claves. Estas claves pueden utilizarse con algoritmos de clave simétrica para transmitir información de forma protegida.
#### Generación de un grupo DH único
Primero hay que generar un nuevo y único grupo Diffie-Hellman, la recomendación es que sea de 2048 bits. La forma más sencilla de hacerlo es utilizar OpenSSL:
```bash
# openssl dhparam -out dhparams.pem 2048
```
Esto puede representar una carga significativa en el servidor mientras se generan los parámetros – siempre se puede evitar este problema potencial mediante la generación de los parámetros en otra máquina y el uso de scp o similar para transferirlos al servidor en cuestión para su uso.
### Postfix – main.cf
Agregar al `main.cf` las siguientes lineas hacia el final del archivo:
Agregamos y ajustamos los demás parámetros:
```bash
# other destination domains should be handled using virtual domains
mydestination = localhost
smtp_host_lookup = dns
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtpd_tls_dh1024_param_file = /etc/ssl/private/dhparams.pem
smtpd_helo_required=yes
#Secure Client-Initiated Renegotiation
# postfix 3.4 and openssl >1.1.1
tls_ssl_options = NO_RENEGOTIATION
#Enable TLS Encryption when Postfix receives incoming emails
smtpd_tls_cert_file=/etc/apache2/md/domains/midominio.edu.ar/pubcert.pem
smtpd_tls_key_file=/etc/apache2/md/domains/midominio.edu.ar/privkey.pem
# Enforce encryption during authentication
smtpd_tls_auth_only=yes
smtpd_tls_loglevel = 1
# Add information about the ciphers used during transfer to the
# message headers
smtpd_tls_received_header = yes
# Encryption is optional. Changing this to encrypt will enforce
# the use of TLS but has the side effect that MTAs without TLS
# capability won't be able to deliver mail to our server.
smtpd_tls_security_level = may
# Disallow any methods that do allow anonymous authentication
smtpd_sasl_security_options = noanonymous, noplaintext
smtpd_sasl_tls_security_options = noanonymous
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
#Enable TLS Encryption when Postfix sends outgoing emails
# Enforce the use of TLS
smtp_tls_security_level = may
smtp_tls_loglevel = $smtpd_tls_loglevel
smtp_tls_mandatory_protocols = $smtpd_tls_mandatory_protocols
smtp_tls_mandatory_ciphers = $smtpd_tls_mandatory_ciphers
smtp_tls_exclude_ciphers = $smtpd_tls_exclude_ciphers
smtp_tls_mandatory_exclude_ciphers = $smtpd_tls_mandatory_exclude_ciphers
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# Negotiate the strongest available cipher available with the remote server.
smtpd_tls_protocols = TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtp_tls_protocols = $smtpd_tls_protocols
smtp_tls_ciphers = high
smtpd_tls_ciphers = high
smtpd_tls_mandatory_protocols = $smtpd_tls_protocols
smtp_tls_mandatory_protocols = $smtpd_tls_protocols
smtp_tls_mandatory_ciphers = high
smtpd_tls_mandatory_ciphers = high
# Exclude some deprecated not so secure ciphers.
smtpd_tls_mandatory_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL
smtpd_tls_exclude_ciphers = $smtpd_tls_mandatory_exclude_ciphers
smtp_tls_mandatory_exclude_ciphers = $smtpd_tls_mandatory_exclude_ciphers
smtp_tls_exclude_ciphers = $smtpd_tls_mandatory_exclude_ciphers
# Postfix will select the cipher used for communication.
tls_preempt_cipherlist = yes
# Disable all OpenSSL bug work-arounds on a 64 bit system
tls_disable_workarounds = 0xFFFFFFFFFFFFFFFF
#Handle SMTP authentication using Dovecot
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
# Don't talk to mail systems that don't know their own hostname.
smtpd_recipient_restrictions =
reject_unknown_sender_domain,
permit_mynetworks,
permit_sasl_authenticated,
# DNSBL (DNS Based Blacklist/Blocklist)
reject_rbl_client zen.spamhaus.org,
reject_rhsbl_reverse_client dbl.spamhaus.org,
reject_rhsbl_helo dbl.spamhaus.org,
reject_rhsbl_sender dbl.spamhaus.org,
# Don't accept mail from domains that don't exist.
smtpd_sender_restrictions =
reject_unknown_sender_domain
# Allow connections from trusted networks and authenticated users.
smtpd_client_restrictions =
permit_mynetworks,
permit_sasl_authenticated
# Relay control: local clients and
# authenticated clients may specify any destination domain.
smtpd_relay_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination
#The size is in Bytes...
mailbox_size_limit = 0 # Ilimitado
message_size_limit = 20971520 # 20 Mb
# using Dovecot's LMTP for mail delivery and giving it path to store mail
virtual_transport = lmtp:unix:private/dovecot-lmtp
# virtual mailbox setups
virtual_alias_maps = mysql:/etc/postfix/mysql/virtual_alias_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql/virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql/virtual_mailbox_maps.cf
```
Deshabilitamos el chroot (predeterminado en Debian) modificando /etc/postfix/master.cf. Debería verse así
```bash
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (100)
# ==========================================================================
smtp unix - - - - - smtp
```
### Verificar certificados
Ninguna configuración está exenta de eventuales problemas. Llegado el caso, estos comandos pueden resultar de utilidad a la hora de enfrentarlos.
Para los certificados públicos
```bash
openssl x509 -in /etc/apache2/md/domains/midominio.edu.ar/pubcert.pem -text -noout
```
Si no está dañado el resultado de este comando debería mostrar, entre otras cosas, los (sub)dominios para los cuales fue creado:
```bash
DNS:campus.midominio.edu.ar, DNS:eventos.midominio.edu.ar, DNS:mapa.midominio.edu.ar, DNS:nube.midominio.edu.ar, DNS:pad.midominio.edu.ar, DNS:reuniones.midominio.edu.ar, DNS:www.midominio.edu.ar
```
En tanto que, para los certificados privados verificamos que contengan una llave válida
```bash
openssl rsa -in /etc/apache2/md/domains/midominio.edu.ar/privkey.pem -text -noout
```
El resultado de este comando debería mostrar algo así:
```bash
RSA key ok
```
## Configuración de Casillas de Correo Virtuales en Postfix
Vamos a utilizar una base de datos mariadb para dominios, usuarios y alias virtuales.
Creamos un directorio separado para almacenar toda la configuración de postfix relacionada con la base de datos:
```bash
# mkdir /etc/postfix/mysql
```
### Mapeo de Alias Virtuales
Creamos el archivo `/etc/postfix/mysql/virtual_alias_maps.cf`
Y pegamos allí lo siguiente:
```bash
user = vimbadmin
password = password
hosts = 127.0.0.1
dbname = vimbadmin
query = SELECT goto FROM alias WHERE address = '%s' AND active = '1'
```
### Mapeo de Dominios Virtuales
Creamos el archivo `/etc/postfix/mysql/virtual_domains_maps.cf`
Y pegamos allí lo siguiente:
```bash
user = vimbadmin
password = password
hosts = 127.0.0.1
dbname = vimbadmin
query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '0' AND active = '1'
```
### Mapeo de Casillas de Correo (usuario) Virtuales
Creamos el archivo `/etc/postfix/mysql/virtual_mailbox_maps.cf`
Y pegamos allí lo siguiente:
```bash
user = vimbadmin
password = password
hosts = 127.0.0.1
dbname = vimbadmin
query = SELECT maildir FROM mailbox WHERE username = '%s' AND active = '1'
```
El comando postmap crea o consulta las tablas de búsqueda de Postfix, o actualiza alguna existente. Ingresamos el siguiente comando para asegurarnos que Postfix puede consultar la tabla de dominios. Reemplazar midominio.edu.ar con el primer valor almacenado. El comando debería devolver 1 si tiene éxito:
```bash
# postmap -q midominio.edu.ar mysql:/etc/postfix/mysql/virtual_domains_maps.cf
```
Probamos Postfix para verificar que puede obtener la primer dirección de correo de la base de datos. Reemplazar raul@midominio.edu.ar con la primer dirección de correo registrada en la tabla. Deberíamos ver un 1 si tiene éxito:
```bash
# postmap -q raul@midominio.edu.ar mysql:/etc/postfix/mysql/virtual_mailbox_maps.cf
```
Por último verificamos que Postfix puede consultar la tabla de alias. Reemplazar alias-raul@midominio.edu.ar con el primer valor de origen creado en la tabla. El comando debería arrojar el valor de destino para la fila:
```bash
# postmap -q alias-raul@midominio.edu.ar mysql:/etc/postfix/mysql/virtual_alias_maps.cf
```
## Configuración de Dovecot
Dovecot es un servidor IMAP y POP. Además implementa seguridad/autenticación para IMAP/POP así como también SMTP (vía Postfix).
Usamos dovecot versión 2.3.4.1. Esto se puede verificar usando el comando:
```bash
# dovecot --version
```
### Un usuario de linux real – vmail
Los siguientes comandos crean un usuario y un grupo llamado vmail. Se trata de un usuario de linux que será propietario de los correos electrónicos de todo el mundo (No hay que entrar en pánico por este hecho…)
```bash
# groupadd -g 5000 vmail
# useradd -g vmail -u 5000 vmail -d /var/vmail -m
```
### Reiniciamos postfix
```bash
# service postfix restart
```
Dovecot está configurado de manera modular con archivos en `/etc/dovecot/conf.d/` que son incluidos desde `/etc/dovecot/dovecof.conf`.
A Efectos prácticos es preferible tener un solo archivo de configuración en lugar de varios, así que
```bash
# doveconf -n > /etc/dovecot/dovecot.conf.new
# mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig
# mv /etc/dovecot/dovecot.conf.new /etc/dovecot/dovecot.conf
# nano /etc/dovecot/dovecot.conf
```
Configurar la ubicación de almacenamiento de correo
```bash
mail_location = maildir:/var/vmail/%d/%n
```
Habilitamos los protocolos necesarios
```bash
# Enable installed protocols
!include_try /usr/share/dovecot/protocols.d/*.protocol
protocols = imap lmtp sieve
```
Buscamos la linea ssl = no, y la eliminamos. Luego insertamos el siguiente bloque:
```bash
service imap-login {
inet_listener imap {
port = 0
}
inet_listener imaps {
port = 993
}
}
ssl = required
ssl_cert =
ServerAdmin administrador@midominio.edu.ar
ServerName vma.midominio.edu.ar
ServerAlias vma.midominio.edu.ar
DocumentRoot /srv/vimbadmin/public
Options FollowSymLinks
AllowOverride FileInfo
Require all granted
ErrorLog ${APACHE_LOG_DIR}/error_vma.log
CustomLog ${APACHE_LOG_DIR}/access_vma.log combined
```
A partir de aquí se puede visitar vma.midominio.edu.ar y crear una cuenta de administrador ViMbAdmin. Por favor, notar que **esta cuenta ViMbAdmin no es** **una cuenta virtual de correo electrónico**.
Es posible agregar dominio, usuarios virtuales de correo electrónico luego de ingresar a vma.midominio.edu.ar usando la cuenta ViMbAdmin.
### Probando la configuración
_Local_
La herramienta cliente de OpenSSL ofrece una manera de conectar y diagnosticar servidores:
```bash
# openssl s_client -starttls smtp -connect midominio.edu.ar:587
# openssl s_client -connect midominio.edu.ar:993
```
ambos comandos deben arrojar
```bash
Verify return code: 0 (ok)
```
como una de las últimas líneas.
_Servidor_
En una nueva terminal, nos conectamos al servidor
```bash
# tail -f /var/log/mail.log
```
para verificar si postfix y dovecot están (re-)arrancando sin inconvenientes:
```bash
# service postfix restart
# service dovecot restart
```
Luego verificamos los puertos 25, 587 y 993 aparecen en la columna ‘Local Address’:
```bash
# netstat -ltnp
```
### Configuración de MUA (Mail User Agent) ej. Mozilla Thunderbird
Correo entrante IMAP:
```bash
Nombre de host: midominio.edu.ar
Puerto: 993
SSL: SSL/TLS
Autenticación: Clave normal
Nombre de usuario: administrador@midominio.edu.ar
```
Correo saliente SMTP:
```bash
Nombre de host: midominio.edu.ar
Puerto: 587
SSL: STARTTLS
Autenticación: Clave normal
Nombre de usuario: administrador@midominio.edu.ar
```
#### Configuración automática de los clientes de correo para IMAP/SMTP
Algunos clientes de correo emplean un sistema denominado “Autodiscover” para averiguar cuáles son los parámetros de uso imap/smtp.
Puedes configurar esto si quieres, básicamente requiere un subdominio y un registro SRV.
Puedes agregar el registro SRV en cualquier dominio para el que quieras usar esta configuración.
Si tienes un certificado SSL global en dovecot para tu nombre de host, esta sería una buena forma de asegurarte de que los clientes utilizan el valor correcto, para que no obtengan errores de certificado SSL.
Supongamos que vas a tener a tus clientes con
```bash
midominio.edu.ar
```
conectados a
```bash
correo.midominio.edu.ar
```
tanto para IMAP como para SMTP.
Creamos un subdominio llamado
```bash
autodiscover.midominio.edu.ar
```
para almacenar el XML.
Configuramos un registro SRV en la zona DNS de midominio.edu.ar:
```bash
_autodiscover._tcp.midominio.edu.ar. 3600 IN SRV 10 10 443 autodiscover.midominio.edu.ar.
```
Luego, creamos el subdominio autodiscover.midominio.edu.ar y añadimos el siguiente código en un archivo llamado autodiscover.php:
```php
(.*?)\<\/EMailAddress\>/", $data, $matches);
//set Content-Type
header("Content-Type: application/xml");
echo ''; ?>
email
settings
IMAP
correo.midominio.edu.ar
993
off
off
on
on
SMTP
correo.midominio.edu.ar
587
off
off
TLS
on
off
off
```
Ten en cuenta que el registro SRV utiliza el puerto 443 para autodiscover.midominio.edu.ar, así que asegúrate de tener una configuración de certificado válida para este subdominio.
Puedes probar yendo a https://autodiscover.midominio.edu.ar para asegurarte de que tienes un candado verde. El script busca la entrada XML en la etiqueta para insertar en el campo de resultado .
Si es necesario, puedes configurar SMTP para usar el puerto 465, pero tendrías que cambiar la de TLS a SSL, ya que el protocolo es diferente en el 465.
El puerto 587 requiere smtp-auth pero se salta algunas comprobaciones de spam y usa STARTTLS para habilitar SSL. El puerto 465 es SSL completo pero los clientes pueden tener problemas para enviar si su IP/rango está en una RBL.
Por último, necesitaremos configurar un archivo .htaccess para que cualquier petición al subdominio autodiscover.midominio.edu.ar resulte en que se llame al autodiscover.php. En el DocumentRoot del subdominio, añade este código:
```bash
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ autodiscover.php [NC,L]
```
##### Thunderbird
A diferencia de la auto-detección de Microsoft, Thunderbird hace un intento directo a http://autoconfig.midominio.edu.ar/mail/config-v1.1.xml?emailaddress=user@midominio.edu.ar
Esto puede ser manejado creando un subdominio llamado “autoconfig”, y en el área web de este subdominio, crear una carpeta llamada “mail”, y dentro de este directorio “mail”, crear un archivo llamado config-v1.1.xml. Una ruta de ejemplo podría ser similar a:
/domains/midominio.edu.ar/public\_html/autoconfig/mail/config-v1.1.xml
Dentro de este archivo, colocamos el código:
```xml
midominio.edu.ar
%EMAILADDRESS%
mail.midominio.edu.ar
993
SSL
%EMAILADDRESS%
password-cleartext
smtp.midominio.edu.ar
587
STARTTLS
%EMAILADDRESS%
password-cleartext
```
## Instalación de Roundcube
Creamos un directorio y nos ubicamos allí:
```bash
# mkdir /srv/roundcube
# cd /srv/roundcube
```
Descargamos y descomprimimos el tar.gz de RoundCube:
```bash
# wget https://github.com/roundcube/roundcubemail/releases/download/1.4.10/roundcubemail-1.4.10-complete.tar.gz
# tar xfz roundcubemail-1.4.10-complete.tar.gz
```
Los archivos de RoundCube ahora están en la carpeta /srv/roundcube/roundcubemail-1.4.10. El próximo paso es moverlos un nivel hacia arriba a /srv/roundcube.
```bash
# mv roundcubemail-1.4.10/* .
# mv roundcubemail-1.4.10/.htaccess .
```
El punto al final de ambos comandos es requerida y parte de la sentencia, ¡no lo olvides! Eliminamos el directorio y el archivo tar.gz.
```bash
# rmdir roundcubemail-1.4.10
# rm roundcubemail-1.4.10-complete.tar.gz
```
Cambiamos la propiedad de todos los archivos al usuario que está utilizando el Apache.
```bash
# chown -R www-data:www-data /srv/roundcube
```
### Instalamos la base de datos de RoundCube
Roundcube requiere una base de datos para almacenar la configuración de la casilla de correo, contactos, etc. Vamos a crear una base de datos con el nombre “roundcubemail” y un usuario con el mismo nombre “roundcube” en MariaDB.
Ingresamos a la consola de MariaDB con el siguiente comando:
```bash
# mysql --defaults-file=/etc/mysql/debian.cnf
```
Luego ejecutamos los siguientes comandos para crear la base de datos y el usuario. Reemplazando “clavesecreta” con la contraseña que prefieras.
```sql
CREATE DATABASE roundcubemail;
GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'clavesecreta';
FLUSH PRIVILEGES;
QUIT
```
Ahora importaremos las tablas de RoundCube desde el archivo mysql.initial.sql en nuestra nueva base de datos. Para ello ejecutamos el comando en la consola de Linux:
```bash
# mysql --defaults-file=/etc/mysql/debian.cnf roundcubemail < /srv/roundcube/SQL/mysql.initial.sql
```
### Configurar RoundCube y Apache
En este paso, vamos a configurar los detalles de la base de datos en RoundCube y también a agregar un archivo de configuración en Apache.
Ejecutamos el siguiente comando para crear un nuevo archivo config.inc.php basado en la configuración de ejemplo y lo abrimos.
```bash
# cd /srv/roundcube/config
# cp -pf config.inc.php.sample config.inc.php
# nano config.inc.php
```
Hallar la linea de configuración de la base de datos que comienza con $config\[‘db\_dsnw’\] y reemplazarla con lo siguiente:
```bash
$config['db_dsnw'] = 'mysql://roundcube:clavesecreta@localhost/roundcubemail';
```
Luego modificamos la configuración predeterminada.
```bash
// The IMAP host chosen to perform the log-in.
$config['default_host'] = 'ssl://correo.midominio.edu.ar';
// TCP port used for IMAP connections
$config['default_port'] = 993;
$config['imap_auth_type'] = PLAIN;
// IMAP socket context options
$config['imap_conn_options'] = array(
'ssl' => array(
'peer_name' => 'correo.midominio.edu.ar',
'verify_peer_name' => true,
'capath' => '/usr/lib/ssl/certs/',
'local_cert' => '/etc/letsencrypt/live/correo.midominio.edu.ar/fullchain.pem',
'verify_peer' => true,
),
);
// SMTP server host (for sending mails).
$config['smtp_server'] = 'tls://correo.midominio.edu.ar';
// SMTP port (default is 25; use 587 for STARTTLS or 465 for the
// deprecated SSL over SMTP (aka SMTPS))
$config['smtp_port'] = 587;
// SMTP socket context options
$config['smtp_conn_options'] = array(
'ssl' => array(
'peer_name' => 'correo.midominio.edu.ar',
'verify_peer_name' => true,
'capath' => '/usr/lib/ssl/certs/',
'local_cert' => '/etc/letsencrypt/live/correo.midominio.edu.ar/fullchain.pem',
'verify_peer' => true,
),
);
// Name your service. This is displayed on the login screen and in the window t$
$config['product_name'] = 'Correo de Mi Dominio';
// List of active plugins (in plugins/ directory)
$config['plugins'] = array(
'password',
...
);
```
Ahora es necesario configurar Apache. Creamos un nuevo archivo de configuración `/etc/apache2/sites-available/roundcube.conf` y agregamos las siguientes lineas:
```bash
ServerAdmin administrador@midominio.edu.ar
ServerName correo.midominio.edu.ar
ServerAlias correo.midominio.edu.ar
DocumentRoot /srv/roundcube
Options FollowSymLinks
AllowOverride None
Options +FollowSymLinks
# AddDefaultCharset UTF-8
AddType text/x-component .htc
RewriteEngine On
RewriteRule ^favicon\.ico$ skins/larry/images/favicon.ico
# security rules:
# - deny access to files not containing a dot or starting with a dot
# in all locations except installer directory
RewriteRule ^(?!installer)(\.?[^\.]+)$ - [F]
# - deny access to some locations
RewriteRule ^/?(\.git|\.tx|SQL|bin|config|logs|temp|tests|program\/(include|lib|localization|steps)) - [F]
# - deny access to some documentation files
RewriteRule /?(README\.md|composer\.json-dist|composer\.json|package\.xml)$ - [F]
SetOutputFilter DEFLATE
ExpiresActive On
ExpiresDefault "access plus 1 month"
FileETag MTime Size
Options -Indexes
AllowOverride None
Require all granted
Options -FollowSymLinks
AllowOverride None
Require all denied
Options -FollowSymLinks
AllowOverride None
Require all denied
Options -FollowSymLinks
AllowOverride None
Require all denied
Options -FollowSymLinks
AllowOverride None
Require all denied
```
Habilitamos la configuración y recargamos apache:
```bash
# a2ensite roundcube
# systemctl reload apache2
```
RoundCube estará disponible desde correo.midominio.edu.ar.
###Complementos de Roundcube
Casi todos tienen su propio archivo de configuración ubicado en el directorio del plugin. Inicialmente este archivo de configuración se llama config.inc.php.dist. Debemos renombrarlo a config.inc.php.
Luego editamos el archivo config.inc.php para comprobar si alguna de las opciones requiere ser modificada. Basta con seguirlas instrucciones proporcionadas en el propio archivo o en el archivo README del plugin.
#### Agregar el complemento a la configuración de Roundcube.
Ahora que el plugin está copiado y configurado, necesitamos indicar a Roundcube que debe ser cargado. Para ello, se debe añadir el nombre del plugin al archivo de configuración principal de Roundcube `/srv/roundcube/config/config.inc.php`
Buscamos la linea $config[‘plugins’] = array(); y agregamos el complemento que deseamos. Por ejemplo, para la gestión de contraseñas sería
```bash
$config['plugins'] = array('password');
```
En caso que ya hubiera algunos complementos, debemos añadir el nombre del nuevo al final de la lista. Por ejemplo, la matriz de podría tener este aspecto:
```bash
$config['plugins'] = array('zipdownload', 'archive');
```
La forma correcta de añadir otro plugin es:
```bash
$config['plugins'] = array('zipdownload', 'archive', 'password');
```
Siguiendo con el ejemplo del complemento para gestionar las contraseñas desde Roundcube, editamos el archivo de configuración de ese complemento: `/srv/roundcube/plugins/password/config.inc.php`
Indicamos el algoritmo de encriptación y las credenciales de acceso a la base de datos.
```bash
/plugins/password/config.inc.php
$config['password_algorithm'] = 'sha512-crypt';
$config['password_dovecotpw'] = '/usr/local/sbin/doveadm pw'; // for dovecot-2.x
$config['password_dovecotpw_method'] = 'SHA512-CRYPT';
$config['password_db_dsn'] = 'mysql://vimbadmin:contraseña@localhost/vimbadmin';
$config['password_query'] = 'UPDATE mailbox SET password=%c,modified=NOW() WHERE username=%u ';
$config['password_crypt_hash'] = 'sha512';
```
En este punto ya tendremos habilitada la opción **Contraseña** dentro de las opciones de **Configuración**
## DKIM, SPF y DMARC
DKIM, SPF y DMARC son estándares que habilitan diferentes aspectos de la autenticación de correo electrónico. Abordan cuestiones complementarias.
* SPF permite a los remitentes definir qué direcciones IP pueden enviar correo para un dominio determinado.
* DKIM proporciona una clave de cifrado y una firma digital que verifica que un mensaje de correo electrónico no fue falsificado o alterado.
* DMARC unifica los mecanismos de autenticación de SPF y DKIM en un marco común y permite a los propietarios de los dominios declarar cómo desean que se maneje el correo electrónico de ese dominio si no pasa una prueba de autorización.
### Instalación Básica
```bash
# apt install opendkim opendkim-tools postfix-policyd-spf-python postfix-pcre
```
Agregar el usuario postfix al grupo opendkim de modo que Postfix pueda acceder al socket de OpenDKIM cuando lo necesite:
```bash
# adduser postfix opendkim
```
## Configurar SPF
### Agregar registros SPF al DNS
```bash
midominio.edu.ar.IN TXT "v=spf1 mx a ip4:170.210.45.130 ip6:2800:110:44:6260::130 a:correo.midominio.edu.ar -all"
```
* La etiqueta v=spf1 es necesaria y tiene que ser la primera.
* La última etiqueta, -all, indica que el correo de nuestro dominio solo debería proceder de los servidores identificados en la cadena SPF.
* mx señala a todos los hosts listados en los registros MX de nuestro dominio.
* La etiqueta a permite identificar un host específico por nombre o dirección IP, con esto podemos definir que hosts están autorizados.
### Agregar el agente de directivas SPF a Postfix
El agente de directivas SPF basado en Python agrega la verificación de directivas SPF a Postfix. El registro SPF para el dominio del remitente del correo entrante será verificado y, si existe, el correo será manejado en consecuencia.
1. Al usar SpamAssassin, puede que querramos editar/etc/postfix-policyd-spf-python/policyd-spf.confpara cambiar la configuración de HELO_rejectyMail_From_rejectaFalse. Esto hará que el agente de directivas SPF ejecute sus pruebas y agregue un mensaje al encabezado con los resultados y no rechace ningún mensaje. Esto también resulta útil si queremos ver los resultados del procesamiento de no aplicarlos al procesamiento de coreo. De otro modo, basta continuar con la configuración estándar.
2. Editamos/etc/postfix/master.cfy agregamos lo siguiente al final:
```bash
policyd-spf unix - n n - 0 spawn user=policyd-spf argv=/usr/bin/policyd-spf
```
3. Abrir/etc/postfix/main.cfy agregar esta entrada para incrementar el timeout del agente de directivas de Postfix, con lo cual evitaremos que Postfix aborte al agente si las transacciones se enlentecen:
policyd-spf\_time\_limit = 3600
4. Editar la entradasmtpd_recipient_restrictionspara agregar check_policy_service:
```bash
smtpd_recipient_restrictions =
...
reject_unauth_destination,
check_policy_service unix:private/policyd-spf,
...
```
Debemos asegurarnos de agregar la entrada check\_policy\_service después de
```bash
reject\_unauth\_destination para evitar que nuestro sistema se convierta en un relay abierto. Si reject\_unauth\_destination es la última entrada en nuestra lista de restricciones, es necesario agregar una coma a continuación de ella y omitir la coma al final de check\_policy\_service.
```
5. Reiniciar Postfix
```bash
systemctl restart postfix
```
Podemos verificar el funcionamiento del agente de directivas buscando en los encabezados originales en del correo entrante el encabezado de resultados SPF. El encabezado que el agente de directivas agrega a los mensajes debería ser similar a este:
```bash
Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=127.0.0.1; helo=mail.midominio.edu.ar; envelope-from=text@midominio.edu.ar; receiver=tknarr@silverglass.org
```
Esto indica una verificación exitosa contra las directivas SPF del dominio remitente. Si cambiamos las directivas definidas en el paso 1 para que no rechace el correo que no pasa la validación SPF, podríamos ver resultados fallidos en este encabezado. Este encabezado no aparecerá en correo saliente o local.
El agente de directivas SPF también registra su actividad en /var/log/mail.log. Allí veremos mensajes como este:
```bash
Jan 7 06:24:44 arachnae policyd-spf[21065]: None; identity=helo; client-ip=127.0.0.1; helo=mail.midominio.edu.ar; envelope-from=test@midominio.edu.ar; receiver=tknarr@silverglass.org
Jan 7 06:24:44 arachnae policyd-spf[21065]: Pass; identity=mailfrom; client-ip=127.0.0.1; helo=mail.midominio.edu.ar; envelope-from=test@midominio.edu.ar; receiver=tknarr@silverglass.org
```
El primer mensaje es una verificación del comando HELO, en este caso indicando que no existe información SPF alguna que coincida con el HELO (lo cual está perfectamente bien). El segundo mensaje es una verificación contra la dirección From, e indica que pasó la verificación y procede de uno de los servidores de envío que el servidor del dominio remitente ha informado que se encuentra habilitado a enviar correo para ese dominio.
Consideraciones:
Existe un bug en las versiones de Bind9 incluidas en Debian por el cual es posible que tengamos mensajes como este en el log:
```bash
found SPF/TXT record but no SPF/SPF record found, add matching type SPF record
```
A partir de 2014 los registros SPF fueron ‘deprecados’ y fueron reemplazados por registros TXT con la información inherente a SPF.
No obstante, habiendo seguido los pasos para configurar el registro SPF en nuestro DNS, el servidor de correo pasará las validaciones.
Configurar OpenDkim
-------------------
Esto implica configurar el paquete OpenDKIM, anexarlo a Postfix, y agregar un registro al DNS.
El archivo principal de configuración de OpenDKIM /etc/opendkim.conf debe verse así:
```bash
# Log to syslog
Syslogyes
# Required to use local socket with MTAs that access the socket as a non-
# privileged user (e.g. Postfix)
UMask002
# OpenDKIM user
# Remember to add user postfix to group opendkim
UserIDopendkim
# Socket smtp://localhost
Socketinet:12301@localhost
# Map domains in From addresses to keys used to sign messages
KeyTable/etc/opendkim/keytable
SigningTablerefile:/etc/opendkim/signingtable
# Hosts to ignore when verifying signatures
ExternalIgnoreListrefile:/etc/opendkim/trustedhosts
InternalHostsrefile:/etc/opendkim/trustedhosts
Selectorcorreo
Canonicalizationrelaxed/simple
Modesv
SubDomainsno
AutoRestartyes
AutoRestartRate10/1M
Backgroundyes
DNSTimeout5
SignatureAlgorithmrsa-sha256
OversignHeadersFrom
```
Aquí el dato clave es el valor que asignemos al selector.
Debemos asegurarnos que los permisos del archivo se definieron correctamente:
```bash
# chmod u=rw,go=r /etc/opendkim.conf
```
Creamos los directorios donde se alojarán los archivos de datos de OpenDKIM, asignamos la propiedad al usuario opendkim, y restringimos los permisos de archivo:
```bash
# mkdir /etc/opendkim
# mkdir /etc/opendkim/keys
# chown -R opendkim:opendkim /etc/opendkim
# chmod go-rw /etc/opendkim/keys
```
Creamos la tabla de firmas /etc/opendkim/signingtable. Debe contener una línea por cada dominio para el cual gestionamos correo. Y cada una de ellas debería verse así:
```bash
*@midominio.edu.ar correo._domainkey.midominio.edu.ar
```
El archivo signingtable le indica a OpenDKIM como usar tus llaves, que remitentes deberían usar cuales selectores para sus firmas. En el ejemplo anterior, estamos señalando que todos (\*) quienes envían correo desde “midominio.edu.ar” deberían usar el selector llamado “correo.” Es importante notar que el comodín \* solamente funcionará si la opción SigningTable usa el prefijo refile: antes del nombre de archivo.
Creamos la tabla de llaves /etc/opendkim/keytable. Debe tener una línea por cada dominio en la tabla de firmas. Cada linea debería verse así:
```bash
correo._domainkey.midominio.edu.ar midominio.edu.ar:correo:/etc/opendkim/keys/correo.private
```
El primer campo conecta las tablas signing y key. Vale aclarar que tanto la tabla signing como la tabla key pueden estar tranquilamente en el /etc/opendkim, solo es cuestión de preferencias.
El segundo campo está dividido en 3 secciones separadas por ‘:’.
* La primera sección es el nombre de dominio para el cual la llave es usada.
* La segunda sección es el selector usado al buscar registros en el DNS. Fue definido en/etc/opendkim.conf
* La tercera sección identifica al archivo que contiene la llave para el dominio.
Creamos el archivo de hosts de confianza /etc/opendkim/trustedhosts. Al igual que las tablas, también podría estar en /etc/opendkim. Su contenido debe ser:
```bash
127.0.0.1
localhost
170.210.45.130
2800:110:44:6260::130
*.midominio.edu.ar
```
Generamos las llaves para cada dominio:
```bash
# opendkim-genkey -b 2048 -h sha256 -r -s correo -d midominio.edu.ar -v
```
Esto generará dos archivos, correo.private con la llave y correo.txt con el registro TXT que tendremos que agregar al DNS.
Debemos asegurarnos que el directorio /etc/opendkim/keys solamente sea accesible por el propietario:
```bash
# chown -R opendkim:opendkim /etc/opendkim
# chmod -R go-rwx /etc/opendkim/keys
```
Conectamos el milter a Postfix:
```bash
# nano /etc/default/opendkim
```
Añadimos la siguiente línea, editamos el número de puerto sólo si se utiliza uno personalizado:
```bash
SOCKET="inet:12301@localhost"
```
Verificamos que OpenDKIM se inicia correctamente:
```bash
# systemctl restart opendkim
```
No debería haber mensajes de error, pero si los hay, así comienza la diversión:
```bash
# systemctl status -l opendkim
```
### Configurar el DNS
Al igual que SPF, DKIM emplea registros TXT para mantener la información acerca de la llave para cada dominio. Es necesario crear un registro TXT para el host correo.\_domainkey para cada dominio por el que gestione correo. Su valor puede ser encontrado en el archivo correo.txt para cada dominio. Estos archivos se ven así:
```bash
correo._domainkey IN TXT ( "v=DKIM1; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5oIUrFDWZK7F4thFxpZa2or6jBEX3cSL6b2TJdPkO5iNn9vHNXhNX31nOefN8FksX94YbLJ8NHcFPbaZTW8R2HthYxRaCyqodxlLHibg8aHdfa+bxKeiI/xABRuAM0WG0JEDSyakMFqIO40ghj/h7DUc/4OXNdeQhrKDTlgf2bd+FjpJ3bNAFcMYa3Oeju33b2Tp+PdtqIwXRZksfuXh7m30kuyavp3Uaso145DRBaJZA55lNxmHWMgMjO+YjNeuR6j4oQqyGwz"
"PaVcSdOG8Js2mXt+J3Hr+nNmJGxZUUW4Uw5ws08wT9opRgSpn+ThX2d1AgQePpGrWOamC3PdcwIDAQAB" ) ; ----- DKIM key correo for midominio.edu.ar
```
Copiamos todo y pegamos ese valor en nuestro archivo de zona de Bind. Luego de algunos retoques, debería verse así:
```bash
correo._domainkey.midominio.edu.ar. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5oIUrFDWZK7F4thFxpZa2or6jBEX3cSL6b2TJdPkO5iNn9vHNXhNX31nOefN8FksX94YbLJ8NHcFPbaZTW8R2HthYxRaCyqodxlLHibg8aHdfa+bxKeiI/xABRuAM0WG0JEDSyakMFqIO40ghj/h7DUc/4OXNdeQhrKDTlgf2bd+FjpJ3bNAFcMYa3Oeju33b2Tp+PdtqIwXRZksfuXh7m30kuyavp3Uaso145DRBaJZA55lNxmHWMgMjO+YjNeuR6j4oQqyGwzPaVcSdOG8Js2mXt+J3Hr+nNmJGxZUUW4Uw5ws08wT9opRgSpn+ThX2d1AgQePpGrWOamC3PdcwIDAQAB"
```
Es necesario repetir esto para cada dominio para el cual gestionemos correo, usando la información del archivo .txt para ese dominio.
#### Probamos la configuración
Para probar las el correcto firmado y verificación de las llaves usamos:
```
# opendkim-testkey -d midominio.edu.ar -s correo
```
Si todo está bien no deberíamos ver ninguna salida. Para tener más información, agregamos -vvv al final del comando. Eso produce una salida detallada. El último mensaje debería ser “key OK”. Justo antes de eso podríamos ver un mensaje “key not secure”. Eso es normal y no es señal de error, se debe a que la DNSSEC no está habilitada en su nombre de dominio. Se trata de un estándar de seguridad para la consulta segura del DNS. La mayoría de los nombres de dominio no tienen habilitada la DNSSEC.
### Vinculamos OpenDKIM a Postfix
Definimos el socket correcto para Postfix en /etc/default/opendkim
```bash
# Command-line options specified here will override the contents of
# /etc/opendkim.conf. See opendkim(8) for a complete list of options.#DAEMON_OPTS=""
#
# Uncomment to specify an alternate socket
# Note that setting this will override any Socket value in opendkim.conf
#SOCKET="local:/var/run/opendkim/opendkim.sock" # default
#SOCKET="inet:54321" # listen on all interfaces on port 54321
#SOCKET="inet:12345@localhost" # listen on loopback on port 12345
#SOCKET="inet:12345@192.0.2.1" # listen on 192.0.2.1 on port 12345
SOCKET="inet:8891@localhost"
```
Editamos `/etc/postfix/main.cf` y agregamos una sección para activar el procesamiento de correo a través del demonio OpenDKIM:
```bash
# OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8891
non_smtpd_milters = $smtpd_milters
```
_Consideraciones:_
_El formato del smtpd:milter (inet:localhost:8891) difiere de la configuración de OpenDKIM (inet:8891@localhost). Invertir el orden host / puerto en uno u otro puede acarrear varias horas de diversión._
_La línea lógica que define la configuración de OpenDKIM en Postfix no puede estar identada, es decir que cada línea de configuración debe comenzar en la columna cero._
Si bien podemos colocar la configuración relativa a postfix en cualquier lugar del archivo. Lo usual es hacerlo a continuación de la entrada
smtpd_recipient_restrictions.
Reiniciamos el demonio OpenDKIM de modo que defina el socket correcto para Postfix:
```bash
# systemctl restart opendkim
```
Reiniciamos Postfix para que comience a utilizar OpenDKIM al procesar correo:
```bash
# systemctl restart postfix
```
#### Verificando que todo funciona
Existen varios servicios en línea para verificar la configuración de nuestro sistema de correo, pero una de las maneras más sencillas de hacerlo es enviar un mensaje a una dirección @gmail.com. En esa cuenta de GMail abrimos el correo enviado y le indicamos “Mostrar original”, veremos algo como esto:
```bash
|ID del mensaje| |
|--------------|----------------------------------------------------------------|
|Creado el: |8 de septiembre de 2017, 15:07 (Entregado después de 5 segundos)|
|De: |drodriguez@midominio.edu.ar |
|Para: |drodriguez@unau.edu.ar |
|Asunto: |isso é só uma prova |
|SPF: |PASS con el IP 170.210.45.133 Más información |
|DKIM: |PASS con el dominio midominio.edu.ar Más información |
|DMARC: |PASS Más información |
```
### Configurar OpenDKIM **para** múltiples dominios
Para hacerlo debes añadir los demás dominios en los archivos signingtable, keytable y trustedhosts.
A continuación, genera las claves DKIM privada/pública y añade la clave pública DKIM en el DNS para los otros dominios. Reinicia OpenDKIM y ya está.
### Opcional: Configurar ADSP (Set up Author Domain Signing Practices)
Como ítem final, podemos agregar una política ADSP a nuestro dominio indicando que todos los correos deben contar con una firma DKIM. Como siempre, lo hacemos agregando un registro TXT:
```bash
_adsp._domainkey.midominio.edu.ar.IN TXT "dkim=all;"
```
Esto no es necesario, pero hacerlo dificulta que cualquiera pueda hacer pasar un correo como de nuestro dominio porque los servidores de destino verán la ausencia de la firma DKIM y rechazarán el mensaje.
### Configurar DMARC (Domain Message Authentication, Reporting & Conformance)
El registro DNS DMARC puede ser agregado para indicar a los servidores de correo que pensamos deben hacer cuando mensajes, alegando ser de nuestro dominio, fallan la validación con SPF y/o DKIM. DMARC solo debería ser definido si tenemos SPF y DKIM configurados y funcionando adecuadamente. Si agregamos el registro DMARC sin tener SPF y DKIM en su lugar, los mensajes de nuestro dominio fallarán la validación lo cual causará que sean descartados o relegados a la carpeta de spam.
El registro DMARC es un registro TXT para el host \_dmarc en nuestro dominio conteniendo los siguientes valores recomendados:
```bash
v=DMARC1;p=reject;sp=none;adkim=r;aspf=r
```
Esto solicita a los servidores de correo que coloquen en cuarentena cualquier mensaje que falle las verificaciones SPF o DKIM. No se solicita informe. Si bien muy pocos servidores implementan el software para generar informes sobren mensajes fallidos, podría ser innecesario solicitarlos. Pero como nunca sabemos lo que nos puede deparar el futuro, agregamos los parámetros necesarios:
```bash
_dmarc.midominio.edu.ar.IN TXT "v=DMARC1;p=reject;sp=none;pct=100;ruf=mailto:administrador@midominio.edu.ar;rua=mailto:administrador@midominio.edu.ar"
```
## Control de SPAM
El filtro de spam se hace en dos etapas:
1. El spam es identificado al ingreso al sistema.
2. El spam es entregado en una carpeta dedicada en la cuenta del usuario.
Estas etapas son cosas separadas. Spamassassin identifica y etiqueta al spam mientras que el plugin Sieve de Dovecot permite colocarlo automáticamente en la carpeta spam del usuario. Primero identificaremos el spam.
### **Verificar la aceptación de correo**
Agregamos un nuevo conjunto de verificaciones a `/etc/postfix/main.cf` para reducir la cantidad de correo que acepta el sistema
```bash
### Para descartar correo mal formado
smtpd_helo_required = yes
strict_rfc821_envelopes = yes
disable_vrfy_command = yes
unknown_address_reject_code = 554
unknown_hostname_reject_code = 554
unknown_client_reject_code = 554
smtpd_helo_restrictions =
permit_mynetworks,
reject_invalid_hostname,
## Al modificar sender_checks, el archivo debe ser regenerado
## usando postmap , para generar una Berkeley DB
regexp:/etc/postfix/helo.regexp,
permit
smtpd_recipient_restrictions =
check_client_access hash:/etc/postfix/helo_client_exceptions,
check_sender_access hash:/etc/postfix/sender_checks,
reject_invalid_hostname,
## Puede provocar problemas con Auth SMTP
reject_non_fqdn_hostname,
##################################
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unknown_sender_domain,
reject_unknown_recipient_domain,
permit_mynetworks,
reject_unauth_destination,
## Agregamos excepciones RBL, al hacer cambios el archivo debe ser regenerado usando
## postmap , para generar una Berkeley DB
check_client_access hash:/etc/postfix/rbl_client_exceptions,
reject_rbl_client cbl.abuseat.org,
reject_rbl_client sbl-xbl.spamhaus.org,
reject_rbl_client bl.spamcop.net,
reject_rhsbl_sender dsn.rfc-ignorant.org
permit
```
Ahora necesitamos crear dos archivos:
El primero `/etc/postfix/helo.regexp` que contendrá:
```bash
/^subdominio\.host\.com$/ 550 No uses mi nombre de host
/^xxx\.yyy\.zzz\.xxx$/ 550 No uses mi dirección IP
/^\[xxx\.yyy\.zzz\.xxx\]$/ 550 No uses mi dirección IP
/^[0-9.]+$/ 550 Tu software no cumple con RFC 2821
/^[0-9]+(\.[0-9]+){3}$/ 550 Tu software no cumple con RFC 2821
```
Esto por sí solo hará que los spammers que intentan enviar el comando helo y hacerse pasar por el servidor que recibe el correo por IP o por nombre de host, así como rechazar algunos de los correos que no cumplen con la RFC 2821.
Luego necesitamos crear `/etc/postfix/helo_client_exceptions`
```bash
# Estas direcciones IP pueden evitar los controles fqdn
# Algún comentario para identificar el IP de abajo
www.xxx.yyy.zzz OK
```
Este archivo es necesario en caso un servidor de correo que se comporta mal no puede enviar el helo correcto y tienes que permitir que se acepte el correo de esa fuente. Cosas como dispositivos independientes, cámaras de CCTV son pobres en el cumplimiento de las normas, por lo que podría tener que hacer una excepción para esto.
Antes de que cualquier cambio en este archivo sea utilizable, hay que ejecutar
```bash
# postmap /etc/postfix/helo_client_exceptions
```
Esto creará un archivo llamado `/etc/postfix/helo_client_exceptions.db`
Más adelante tenemos `/etc/postfix/sender_checks` que permite evitar varios controles FQDN y habilitar un remitente determinado. Esto resulta particularmente útil cuando si una empresa tiene un midominio.edu.ar para trabajar pero el correo funcionar en interno.midominio.edu.ar y no hay configuración DNS para interno.midominio.edu.ar, estos es genial para la seguridad pero los DNS externos desconocen la existencia de tal estructura interna y, a consecuencia de ello, postfix rechazará interno.midominio.edu.ar.
```bash
usuario@midominio.edu.ar REJECT
usuario@interno.midominio.edu.ar OK
```
Una vez modificado el archivo es necesario crear una Berkely DB usando:
```bash
# postmap /etc/postfix/sender_checks
```
Luego tenemos las verificaciones RBL. Existen muchos sitios dedicados a ello (en el ejemplo hay 4) que brindan listas actualizadas constantemente con IPs y nombres de host que los spammers utilizan para enviar correo. Cada IP que intenta enviar correo a nuestro servidor de correo será verificado contra esas listas y si la IP no está listada en las RBLs, el servidor aceptará el correo. Eventualmente los servidores pueden aparecer listados y removerlos puede demorar 24 horas luego de un brote de spam de modo que siempre es bueno contar con una manera de evitar los controles.
Para hacerlo creamos un archivo llamado `/etc/postfix/rbl_client_exceptions`
```bash
## Algún comentario
www.xxx.yyy.zzz OK
```
Una vez más será necesario generar la Berkeley DB
```bash
postmap /etc/postfix/rbl_client_exceptions
```
### Instalar Spamassassin
```bash
# apt install spamassassin spamc
```
Creamos un usuario para spamc. Se trata de la mitad cliente de la pareja spamc/spamd. Debería ser usado en lugar de “spamassassin” en scripts para procesar el correo. Leerá el correo desde STDIN, y lo pondrá en la cola de su conexión a spamd, luego leer el resultado y lo imprime a STDOUT. Spamc tiene un impacto muy bajo en el rendimiento, por lo que debería ser mucho más rápida su carga comparado con el programa spamassassin completo.”
```bash
# adduser spamd --disabled-login
```
Basta con presionar enter ante cada pregunta.
Habilitamos el inicio de Spamassassin en cada arranque:
```bash
# systemctl enable spamassassin.service
```
Editamos `/etc/default/spamassassin`
```bash
OPTIONS="--create-prefs --max-children 5 --username spamd --helper-home-dir /home/spamd/ -s /home/spamd/spamd.log"
# Habilita la actualización automática de las reglas de Spamassassin cada noche.
CRON=1
```
Luego editamos /etc/spamassassin/local.cf para establecer las reglas de SPAM:
```bash
rewrite_header Subject ***** SPAM _SCORE_ *****
# Muestra el mensaje spam original en lugar de un mensaje
# que contenga al correo con spam como adjunto.
report_safe 0
required_score 5.0
use_bayes 1
bayes_auto_learn 1
skip_rbl_checks 0
use_dcc 0
use_pyzor 0
```
Iniciamos el filtro de spam:
```bash
# systemctl start spamassassin
```
Le indicamos a Postfix que tenemos activo un filtro de contenido. En `/etc/postfix/master.cf` encontrar la linea
```bash
smtp inet n - - - - smtpd
```
y directamente debajo agregamos:
```bash
-o content_filter=spamassassin
```
En este caso la linea que comienza con -o debe tener uno o más espacios en blanco al comienzo. De no ser así, al recargar la configuración Postfix ‘dirá’: “/usr/sbin/postconf: fatal: invalid type field”. Nuevamente, incontables horas de diversión.
Ya que postfix enviará el recipiente a spamc, necesitamos indicarle a postfix que entregue el correo a cada usuario de separadamente. Agregamos la siguiente linea a /etc/postfix/main.cf
```bash
spamassassin_destination_recipient_limit = 1
```
Necesitamos indicar a Postfix que encamine el correo a spamd. Para ello, al final de `/etc/postfix/master.cf` agregamos:
```bash
spamassassin unix - n n - - pipe
user=spamd argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}
```
Nuevamente hay que tener en cuenta el espacio al comienzo de la segunda linea.
```bash
# systemctl restart spamassassin
# postfix reload
```
En este punto es necesario enviar un correo de prueba hacia y desde nuestra cuenta en Roundcube para cerciorarnos que aún funciona.
Si no fuera así, removemos las últimas entradas de /etc/postfix/master.cf, reiniciamos Postfix e intentamos nuevamente. Verificamos no haber ingresado algo mal y que al reiniciar Postfix no arroja ningún error. Solamente vamos a continuar si el envío y la recepción funcionan.
### Probando el filtro de spam
Enviamos un correo a nuestro recipiente con el GTUBE. Es el EICAR para los filtros de spam: es una cadena especial de caracteres que los filtros de spam reconocen como tal para propósito de pruebas. Más en: http://spamassassin.apache.org/gtube/
Así que enviamos un correo con esta cadena en el cuerpo del mensaje:
```bash
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
```
Al ingresar a Roundcube el mensaje debería estar etiquetado como \*\*\*\*\*SPAM\*\*\*\*\*. Un mensaje sin esta cadena no debería contener esa alerta.
Abrimos el mensaje etiquetado como \*\*\*\*\*SPAM\*\*\*\*\* y vamos a “Mostrar código”.
Deberíamos ver algo así:
```bash
X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on servidor
X-Spam-Flag: YES
X-Spam-Level: **************************************************
X-Spam-Status: Yes, score=1001.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID,
DKIM_VALID_AU,FREEMAIL_FROM,GTUBE,PYZOR_CHECK,RCVD_IN_MSPIKE_H2,
SPF_PASS autolearn=no autolearn_force=no version=3.4.2
X-Spam-Report:
* 1000 GTUBE BODY: Generic Test for Unsolicited Bulk Email
```
### Mover automáticamente el spam a la carpeta Basura
Esto es en realidad parte de algo más grande, llamado sistema de filtrado de correo. Usando filtros (también llamados reglas) podemos aplicar acciones a correo usando lógica, por ejemplo mover correo que está etiquetado como spam a la carpeta Basura.
### Suscribir automáticamente usuarios a las carpetas especiales IMAP
En primer lugar necesitamos asegurarnos que el cliente IMAP está suscripto a la carpeta a la que el spam será movido.
Al abrir Roundcube vemos que solo existen dos carpetas: Entrada y Enviados. Apuntamos a subscribir automáticamente los usuarios a varias carpetas IMAP especiales de modo que siempre estén allí. En /etc/dovecot/dovecot.conf agregamos:
```bash
namespace inbox {
mailbox Drafts {
special_use = \Drafts
auto = subscribe
}
mailbox Junk {
special_use = \Junk
auto = subscribe
}
mailbox Trash {
special_use = \Trash
auto = subscribe
}
#mailbox Archive {
# special_use = \Archive
# auto = subscribe
}
mailbox Sent {
special_use = \Sent
auto = subscribe
}
#mailbox "Sent Messages" {
# special_use = \Sent
#}
}
```
A las carpetas comentadas Roundcube no las reconoce, pero puede ser que algún otro MUA sí lo haga.
Luego
```bash
# dovecot reload
```
y volvemos a entrar a Roundcube ya que las carpetas especiales son creadas al ingresar.
### Sieve
Dovecot cuenta con un plugin llamado Managesieve que permite definir reglas de filtrado en el servidor IMAP, de modo que todos los clientes veran lo mismo independientemente de la plataforma.
Para habilitarlo, en `/etc/dovecot/dovecot.conf` agregamos:
```bash
protocol lmtp {
mail_plugins = $mail_plugins sieve
postmaster_address = administrador@midominio.edu.ar
}
plugin {
sieve = file:~/sieve;active=~/.dovecot.sieve
}
```
Luego reiniciamos dovecot
```bash
# systemctl restart dovecot
```
Probamos la conexión
```bash
# telnet localhost 4190
```
Deberíamos obtener algo así
```bash
Connected to localhost.
Escape character is '^]'.
"IMPLEMENTATION" "Dovecot Pigeonhole"
"SIEVE" "fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date ihave"
"NOTIFY" "mailto"
"SASL" "PLAIN LOGIN"
"VERSION" "1.0"
OK "Dovecot ready."
```
lo cual significa que Sieve está funcionando. Hay que presionar Enter tres veces para salir.
Si surgen inconvenientes, es necesario verificar la configuración, reiniciar Dovecot y volver a intentar.
```bash
# doveconf -n
```
puede ayudar a comprobar errores de tipeo y cosas por el estilo.
Es posible crear reglas sieve predeterminadas. Esto tiene una enorme contra: tan pronto como el usuario crea sus propias reglas (por ejemplo, define una respuesta automática para cuando no está en la oficina) las reglas predeterminadas ya no son tenidas en cuenta aún luego de eliminar la regla personal.
### Definir regla de spam de manera global
Vamos a definir una regla de spam global que moverá el spam automáticamente a la carpeta Basura del usuario.
```bash
sieve_default = /etc/dovecot/sieve/spamfilter.sieve
```
Esta carpeta y archivo son arbitrarios pero me parecieron lógicos.
Creamos la carpeta `/etc/dovecot/sieve`
Cambiamos permisos ya que de no hacerlo dovecot se va a quejar.
```bash
# chown dovecot:dovecot /etc/dovecot/sieve/ -R
```
En /etc/dovecot/sieve/spamfilter.sieve
```bash
require ["fileinto"];
if header :contains "X-Spam-Flag" "YES" {
fileinto "Junk";
}
```
Esta regla verifica un encabezado llamado ‘X-Spam-Flag’. Si contiene YES el mensaje es almacenado en la carpeta Basura.
Recargamos Dovecot y enviamos un mensaje con la cadena GTUBE para verificar si funciona.
### Eliminar spam automáticamente luego de 30 días
Usando doveadm podemos eliminar automáticamente todo el correo en la carpeta Basura más antiguo que cierto tiempo, por ejemplo 30 días.
Doveadm es es la utilidad de administración de Dovecot. Con man doveadm se puede consulta por mayor información sobre la utilidad. Otra lectura relevante para este caso: man doveadm-search y man doveadm-search-query.
Digamos que queremos buscar todos los documentos en todas las bandejas de entrada de más de cuatro horas de antigüedad:
```bash
# doveadm search -A mailbox Inbox savedbefore 4h
administrador@midominio.edu.ar 74b4db2757f9f05661350000595b2a1f 1
administrador@midominio.edu.ar 74b4db2757f9f05661350000595b2a1f 2
```
**-A** significa revisar todas las casillas, no solo la especificada.
No queremos buscar solo la Bandeja de entrada y queremos correo de más de 30 días:
```bash
# doveadm search -A mailbox Junk savedbefore 30d
administrador@midominio.edu.ar 4adeeb2ca5c1ca565c3b000038e0142a 1
administrador@midominio.edu.ar 4adeeb2ca5c1ca565c3b000038e0142a 2
administrador@midominio.edu.ar 4adeeb2ca5c1ca565c3b000038e0142a 3
```
Para más información sobre el formato de consulta.
```bash
$ man doveadm-search-query
```
Pero no queremos buscar solamente sino eliminar esos correos. (Usamos search primero para verificar que obtenemos los resultados que estábamos esperando.)
```bash
# doveadm expunge -A mailbox Junk savedbefore 30d
```
Como seguramente no vamos a querer correr esto manualmente todos los días. Lo programamos:
```bash
# crontab -e
```
Agregamos esta línea:
```bash
@hourly /usr/bin/doveadm expunge -A mailbox Junk savedbefore 30d
```
En caso que no querramos recibir un aviso por correo sobre la salida de esta programación la cambiamos a
```bash
@hourly /usr/bin/doveadm expunge -A mailbox Junk savedbefore 30d > /dev/null 2>&1
```
Lo anterior ejecutará el comando cada hora. Cambiarlo a
```bash
@daily /usr/bin/doveadm expunge -A mailbox Junk savedbefore 30d > /dev/null 2>&1
```
hará que se ejecute cada día
## Postscreen – Reducir la sobrecarga del servidor SMTP
Postfix puede generar hasta 100 procesos de servidor SMTP para manejar las conexiones de clientes SMTP. Se puede comprobar el límite de procesos ejecutando el siguiente comando.
```bash
# postconf default_process_limit
default_process_limit = 150
```
Si hay spambots intentando acceder constantemente al servidor, habrá menos procesos de Postfix para aceptar mensajes de correo legítimos. Y cuando el número de clientes SMTP excede el número de procesos del servidor Postfix, otros clientes SMTP deben esperar hasta que un proceso del servidor esté disponible.
Al bloquear los spambots con Postscreen, podemos reservar los procesos del servidor para los clientes SMTP legítimos. Postscreen está diseñado como una primera capa de defensa contra los spammers. Está implementado como un único proceso que escucha en el puerto 25 y puede manejar múltiples conexiones SMTP entrantes.
### Medidas utilizadas por Postscreen contra los spambots
La mayoría de los spambots tienen una implementación defectuosa del protocolo SMTP. Postscreen puede aprovechar este hecho y utilizar varias medidas para bloquearlos.
* Prueba de saludo previo. Si el cliente SMTP habla antes de su turno, detiene la conexión.
* Comprobación de la lista negra en tiempo real. Si la dirección IP del cliente está en una lista negra, como la de Spamhaus, interrumpe la conexión.
* Prueba profunda de protocolo.
#### Paso 1: Habilitar Postscreen en Postfix
Postscreen se introdujo por primera vez en Postfix 2.8. Si estás usando cualquier distribución de Linux actual, deberías tener Postfix 3.0 o superior. Para comprobar la versión de Postfix, ejecutar
```bash
# postconf mail_version
mail_version = 3.3.0
```
Editar `/etc/postfix/master.cf`
Comentar la siguiente línea
```bash
smtp inet n - y - - smtpd
```
Luego descomentar las siguientes 4 líneas
```bash
smtp inet n - y - 1 postscreen
smtpd pass - - y - - smtpd
dnsblog unix - - y - 0 dnsblog
tlsproxy unix - - y - 0 tlsproxy
```
Donde:
* Las dos primeras líneas activan Postscreen. Tanto Postscreen como el demonio smtpd escucharán en el puerto 25. Postscreen comprobará primero el cliente SMTP y luego pasará la conexión al demonio smtpd.
* El servicio dnsblog (DNS Blacklist Logger) permite registrar las comprobaciones de la lista negra de DNS.
* El servicio tlsproxy habilita el soporte de STARTTLS para postscreen, por lo que los clientes SMTP remotos pueden establecer una conexión encriptada cuando Postscreen está habilitado.
Guardar y cerrar el archivo.
#### Crear una lista blanca/negra permanente
Editar `/etc/postfix/main.cf`
Necesitamos añadir nuestras propias direcciones IP a la lista blanca de Postscreen para que nuestras propias peticiones SMTP no sean comprobadas por Postscreen (prueba de saludo previo, comprobación de la lista negra, test de protocolo profundo, etc). Añadir las siguientes dos líneas al final del archivo.
```bash
postscreen_access_list = permit_mynetworks cidr:/etc/postfix/postscreen_access.cidr
postscreen_blacklist_action = drop
```
Guardar y cerrar el archivo. El valor permit\_mynetworks pondrá en la lista blanca cualquier dirección IP listada en el parámetro mynetworks.
También se pueden añadir manualmente direcciones IP adicionales en el archivo `/etc/postfix/postscreen_access.cidr`.
Es posible que necesitemos poner en la lista blanca la dirección IPv4 e IPv6 pública del servidor de correo. Así que agregamos las siguientes líneas en el archivo. Tener en cuenta que se debe utilizar la notación CIDR: Para una única dirección IPv4, añadir /32 al final; Para una única dirección IPv6, añadir /128 al final.
```bash
#permitir mis propias direcciones IP.
179.0.132.51/32 permit
2800:110:5::66/128 permit
```
Para poner una dirección IP en la lista negra de forma permanente
```bash
12.34.56.78/32 reject
```
Guardar y cerrar el archivo. Reiniciar Postfix para que los cambios surtan efecto.
```
systemctl restart postfix
```
% Postscreen escucha en el puerto 25 solamente, así que los usuarios autenticados del puerto 587 o 465 no serán afectados por Postscreen.
El propio Postscreen también mantiene una lista blanca dinámica para minimizar el retraso de los correos legítimos, definida por el parámetro postscreen\_cache\_map.
```bash
# postconf postscreen_cache_map
postscreen_cache_map = btree:$directory/postscreen_cache
```
Cada dirección IP de la lista blanca dinámica tiene un tiempo de vida.
#### Paso 2: Prueba de saludo previo
Hay una prueba de saludo previo en Postscreen para detectar el spam. En el protocolo SMTP, el servidor SMTP receptor debe declarar siempre su nombre de host antes de que lo haga el servidor SMTP emisor. Algunos spammers violan esta regla y declaran sus nombres de host antes de que lo haga el servidor SMTP receptor.
Postscreen habilita la prueba de saludo previo de manera predeterminada, pero no hará nada con el resultado de la prueba. Como se puede ver en las siguientes líneas de log de ejemplo, el texto “PREGREET” indica que el cliente SMTP declaró su nombre de host primero, pero Postscreen igualmente pasó la conexión al demonio smtpd de Postfix.
```bash
mail postfix/postscreen[24075]: CONNECT from [156.96.118.171]:62604 to [23.254.225.226]:25
mail postfix/postscreen[24075]: PREGREET 11 after 0.07 from [156.96.118.171]:62604: EHLO User\r\n
mail postfix/smtpd[24076]: connect from unknown[156.96.118.171]
mail postfix/smtpd[24076]: disconnect from unknown[156.96.118.171] ehlo=1 quit=1 commands=2
```
Para rechazar clientes SMTP que violan esta regla, editar el archivo main de configuración de Postfix.
```bash
/etc/postfix/main.cf
```
Agregar la siguiente linea al final.
```bash
postscreen_greet_action = enforce
```
Guardar y cerrar el archivo. Luego reiniciar Postfix.
```bash
systemctl restart postfix
```
A partir de ahora, Postscreen detendrá la conexión si un cliente SMTP viola esta regla. Como se puede ver en el siguiente registro, Postscreen detuvo la conexión, por lo que el spammer no tiene la oportunidad de acosar al demonio smtpd.
```bash
mail postfix/postscreen[6471]: CONNECT from [192.241.239.123]:48014 to [23.254.225.226]:25
mail postfix/postscreen[6471]: PREGREET 19 after 0 from [192.241.239.123]:48014: EHLO zg-0131a-136\r\n
mail postfix/postscreen[6471]: DISCONNECT [192.241.239.123]:48014
```
Postscreen sigue permitiendo que se completen otras pruebas antes de detener la conexión. Para interrumpir la conexión inmediatamente sin realizar otras pruebas, utilizar la siguiente configuración en su lugar.
```bash
postscreen_greet_action = drop
```
#### Paso 3: Uso de listas negras y blancas públicas
El parámetro `postscreen_dnsbl_sites` puede ser utilizado para comprobar la dirección IP del cliente SMTP contra las listas negras públicas (DNSBL). Es posible que ya esté utilizando el reject\_rbl\_client de Postfix smtpd para rechazar un cliente SMTP si su dirección IP está en una lista negra pública. Sin embargo, eso puede causar falsos positivos porque la dirección IP de un servidor SMTP inocente podría estar en una lista negra por cualquier razón, incluso si usas permit\_dnswl\_client para verificar también contra la lista blanca pública (DNSWL).
Para reducir los falsos positivos, Postscreen le permite comprobar múltiples listas negras y añadir un factor de peso a cada lista negra. Por ejemplo, si una dirección IP está en la lista negra de Spamhaus, añade 3 puntos; si una dirección IP está en la lista negra de BarracudaCentral, añade 2 puntos. Si la puntuación combinada es lo suficientemente alta (definida por postscreen\_dnsbl\_threshold), rechaza el cliente SMTP. Este sistema de puntuación es similar al de SpamAssassin.
En la siguiente configuración, fijamos el umbral en 3 puntos. Spamhaus tiene un peso de 3. BarracudaCentral tiene un peso de 2. SpamCop tiene un peso de 1. Si la puntuación combinada es igual o mayor que 3, Postscreen rechazaría el cliente SMTP.
```bash
postscreen_dnsbl_threshold = 3
postscreen_dnsbl_action = enforce
postscreen_dnsbl_sites =
zen.spamhaus.org*3
b.barracudacentral.org=127.0.0.[2..11]*2
bl.spameatingmonkey.net*2
bl.spamcop.net
dnsbl.sorbs.net
```
También se puede usar `postscreen_dnsbl_sites` para verificar la dirección IP del cliente SMTP contra la lista blanca pública (DNSWL). Si la dirección IP del cliente está en la lista blanca, agregar puntaje negativo.
```bash
postscreen_dnsbl_sites =
zen.spamhaus.org*3
b.barracudacentral.org=127.0.0.[2..11]*2
bl.spameatingmonkey.net*2
bl.spamcop.net
dnsbl.sorbs.net
swl.spamhaus.org*-4,
list.dnswl.org=127.[0..255].[0..255].0*-2,
list.dnswl.org=127.[0..255].[0..255].1*-4,
list.dnswl.org=127.[0..255].[0..255].[2..3]*-6
```
Si utiliza el parámetro `reject_rbl_client` o `permit_dnswl_client` de Postfix smtpd, se debería eliminarlos, para que el demonio smtpd no realice comprobaciones de IP de nuevo después de Postscreen. Postscreen no comprueba el nombre de dominio basado en la lista negra/blanca, por lo que deberíamos seguir utilizando reject\_rhsbl para realizar la búsqueda de nombres de dominio en las listas negras públicas.
```bash
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
...
...
reject_rhsbl_helo dbl.spamhaus.org,
reject_rhsbl_reverse_client dbl.spamhaus.org,
reject_rhsbl_sender dbl.spamhaus.org,
```
Guardar y cerrar el archivo de configuración main de Postfix. Luego reiniciar Postfix para que los cambios surtan efecto.
```bash
systemctl restart postfix
```
% Si ve el siguiente mensaje en su registro de correo, significa que la dirección IP del cliente SMTP no está en la lista blanca (list.dnswl.org). Esto no es un error.
```bash
warning: dnsblog_query: lookup error for DNS query 179.0.132.51.list.dnswl.org: Host or domain name not found. Name service error for name=179.0.132.51.list.dnswl.org type=A: Host not found, try again
```
Si está en la lista blanca, el mensaje será como este:
```bash
postfix/dnsblog[21188]: addr xx.xx.xx.xx listed by domain list.dnswl.org as 127.0.10.0
```
Si una dirección IP aparece como 127.0.0.255 en list.dnswl.org, como en el siguiente mensaje, significa que ha alcanzado el límite de consulta. Se eberá ejecutar un DNS local propio.
```bash
postfix/dnsblog[11951]: addr 202.66.174.152 listed by domain list.dnswl.org as 127.0.0.255
```
Es necesario tener en cuenta también que [BarracudaCentral Blocklist](http://www.barracudacentral.org/account/register) requiere un registro, que es gratuito. Después de crear una cuenta, simplemente hay que añadir la dirección IP del DNS y ya está.
#### Utilizar DNS local propio
Debemos tener en cuenta que se debe configurar un DNS local cuando se utilicen listas negras y blancas públicas, porque la mayoría de ellas tienen un límite de consultas. Si se emplea un DNS público como 8.8.8.8, es probable que se alcance el límite de consulta antes de lo pensado.
#### Algunos sitios DNSBL muertos o cerrados
No se debe utilizar sitios DNSBL muertos o cerrados, o el servidor de correo rechazará correos legítimos.
**dnsbl.njabl.org**: está desactivado desde 2013.
**dnsbl.ahbl.org**: el acceso público a la lista finalizó en 2015.
#### Paso 4: Habilitar las pruebas de protocolo profundo
Hay 3 pruebas profundas de protocolo comunes en Postscreen:
* Prueba de canalización SMTP
* Prueba de comandos no SMTP
* Prueba de línea nueva vacía
La canalización es una extensión del protocolo SMTP. Permite al cliente SMTP enviar múltiples comandos SMTP a la vez sin esperar la respuesta del servidor SMTP. Postfix los soporta de manera predeterminada. Para comprobarlo, se puede utilizar telnet para conectar al servidor de correo.
```bash
telnet correo.midominio.edu.ar 25
```
A continuación, utilizar el comando EHLO para declarar el nombre de host.
```
EHLO mail.google.com
```
La respuesta del servidor SMTP que aparece a continuación indica que admite la canalización.
```bash
250-PIPELINING
250-SIZE 157286400
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
```
Luego cerrar la conexión.
```bash
quit
```
Algunos spammers utilizan la canalización de comandos para emitir varios comandos RCPT TO: a la vez, con el fin de enviar spam a varios destinatarios en una sesión SMTP. Si el servidor SMTP no anuncia el soporte de canalización, entonces el cliente SMTP no debería emitir múltiples comandos a la vez.
Agregar las siguientes dos líneas en el archivo /etc/postfix/main.cf para habilitar la prueba de canalización y rechazar a los clientes SMTP que fallen esta prueba.
```bash
postscreen_pipelining_enable = yes
postscreen_pipelining_action = enforce
```
Como el nombre sugiere, la prueba de comandos no SMTP hace que Postscreen detecte clientes SMTP que envían comandos no SMTP. Agregar las siguientes dos líneas en el archivo /etc/postfix/main.cf para rechazar tales clientes SMTP.
```bash
postscreen_non_smtp_command_enable = yes
postscreen_non_smtp_command_action = enforce
```
Un problema de vieja data para los administradores de sistemas, debido al diferente soporte de los distintos sistemas operativos, es la diferencia entre los retornos de carro y los saltos de línea, conocidos como y , respectivamente, en SMTP.
La prueba de nuevas líneas limpias permite a Postscreen detectar clientes SMTP que terminan una línea con , en lugar del estándar . Agregar las siguientes dos líneas en el archivo /etc/postfix/main.cf para rechazar tales clientes SMTP.
```bash
postscreen_bare_newline_enable = yes
postscreen_bare_newline_action = enforce
```
Guardar y cerrar el archivo. A continuación, reiniciar Postfix para que los cambios surtan efecto.
```bash
systemctl restart postfix
```
#### El efecto de greylisting de las pruebas de protocolo profundas
La limitación de las pruebas de protocolo profundas es que Postscreen desconectaría a los nuevos clientes SMTP sin importar si las pruebas se superan o no. Postscreen desconecta cada cliente con el siguiente mensaje:
```bash
450 4.3.2 Service currently unavailable
```
Y el cliente debe volver a intentarlo más tarde desde la misma dirección IP. Esto es efectivamente una forma de greylisting, por lo que se necesita desactivar otras formas de greylisting. Por ejemplo, si se usa Postgrey como servidor de política de greylisting, entonces en el archivo /etc/postfix/main.cf hay que comentar la línea
```bash
check_policy_service inet:127.0.0.1:10023,
```
Guardar y cerrar el archivo. Luego reiniciar Postfix.
```bash
systemctl restart postfix
```
#### Cómo minimizar la mala experiencia del usuario
Las listas grises son bastante molestas para el usuario final, ya que éste tiene que esperar varios minutos más para que le llegue el correo electrónico. Para minimizar esta mala experiencia, hay 3 formas posibles cuando se utilizan las pruebas de protocolo profundo de Postscreen.
* Crear un segundo registro MX que apunte a la misma dirección IP.
* Si la dirección IP de un cliente SMTP está en una lista blanca pública, omitir las pruebas profundas de protocolo.
* Utilizar Postwhite para añadir direcciones IP buenas y conocidas a la lista blanca de Postscreen.
##### Crear un segundo registro MX que apunte a la misma dirección IP
Se puede especificar más de un registro MX para el nombre de dominio como se indica a continuación.
```bash
Registro Nombre Servidor de Correo Prioridad
MX @ correo.midominio.edu.ar 0
MX @ correo.midominio.edu.ar 5
```
El remitente intentará el primer servidor de correo (con prioridad 0). Si correo.midominio.edu.ar rechaza el correo por greylisting, entonces el remitente intentará inmediatamente el segundo servidor de correo (con prioridad 5).
El greylisting en Postscreen no tiene un tiempo de retraso como en Postgrey. Si los dos nombres de host del servidor de correo tienen la misma dirección IP, entonces cuando el remitente intente el segundo, el correo electrónico será aceptado inmediatamente (si todas las demás comprobaciones pasan) y los usuarios finales no notarán el retraso del correo electrónico causado por la lista gris.
Tener en cuenta que no todos los servidores de correo intentarán inmediatamente el segundo host MX. Algunos, como Gmail, usarán una dirección IP diferente para intentarlo de nuevo, que por supuesto será rechazada de nuevo. Postfix intentaría el segundo host MX.
##### Omitir pruebas de protocolo profundas si la dirección IP de un cliente SMTP está en una lista blanca pública
Gmail nunca volverá a intentar enviar un correo electrónico desde la misma dirección IP. Sin embargo, la dirección IP de Gmail está en list.dnswl.org. Podemos decirle a Postscreen que ignore a estos clientes SMTP. Añadir la siguiente línea en el archivo /etc/postfix/main.cf para ignorar a los clientes cuya puntuación sea igual a -2 o inferior.
```bash
postscreen_dnsbl_whitelist_threshold = -2
```
Reiniciar Postfix para que los cambios surtan efecto.
```bash
systemctl restart postfix
```
El siguiente mensaje del log de correo indica que Postscreen no realizó pruebas de protocolo profundas y pasó la conexión al demonio smtpd porque la dirección IP de Gmail está en la lista blanca pública.
```bash
Feb 10 10:31:14 mail postfix/postscreen[16579]: CONNECT from [209.85.166.44]:38543 to [23.254.225.226]:25 Feb 10 10:31:14 mail postfix/dnsblog[16582]: addr 209.85.166.44 listed by domain list.dnswl.org as 127.0.5.0 Feb 10 10:31:15 mail postfix/postscreen[16579]: PASS NEW [209.85.166.44]:38543 Feb 10 10:31:15 mail postfix/smtpd[16639]: connect from mail-io1-f44.google.com[209.85.166.44]
```
De hecho, la mayoría de los principales proveedores de correo (Gmail, Hotmail/Outlook, Yahoo Mail, GMX Mail, ProtonMail, etc) están en la lista blanca de list.dnswl.org. También incluye servidores de correo de otros sectores, como puede verse en [dnswl.org](https://www.dnswl.org/?page_id=15).
Así que el uso de postscreen\_dnsbl\_whitelist\_threshold ayudará a omitir el greylisting la mayor parte del tiempo.
##### Uso de Postwhite
Postwhite es un script escrito por Steve Jenkins para generar automáticamente una lista blanca de IPs estáticas para Postscreen utilizando los registros SPF publicados de webmailers conocidos, redes sociales, proveedores de comercio electrónico y remitentes masivos que cumplen con los requisitos. De debe teern en cuenta que esta lista blanca hace que Postscreen omita todas las pruebas (prueba de saludo previo, comprobación de lista negra/lista blanca pública, pruebas de protocolo profundas) para las direcciones IP de la lista blanca, por lo que ayudará a reducir la carga de Postscreen y las solicitudes de DNS a las listas negras/listas blancas públicas.
Para usar Postwhite, primero ir a `/usr/local/bin/`.
Instalar git.
```bash
apt install git
```
Clonar los repositorios SPF-Tools y Postwhite de Github.
```bash
git clone https://github.com/spf-tools/spf-tools.git
git clone https://github.com/stevejenkins/postwhite.git
```
Copiar el archivo postwhite.conf a /etc/.
```bash
cp /usr/local/bin/postwhite/postwhite.conf /etc/
```
Ejecutar Postwhite.
```bash
/usr/local/bin/postwhite/postwhite
```
La lista blanca ser guarda como `/etc/postfix/postscreen_spf_whitelist.cidr`. Editar el `main.cf` de Postfix.
En la linea
```bash
postscreen_access_list = permit_mynetworks cidr:/etc/postfix/postscreen_access.cidr
```
Agregar el archivo de lista blanca
```bash
postscreen_access_list = permit_mynetworks cidr:/etc/postfix/postscreen_access.cidr cidr:/etc/postfix/postscreen_spf_whitelist.cidr
```
Guardar y cerrar el archivo. Luego reiniciar Postfix para que los cambios surtan efecto.
```bash
systemctl restart postfix
```
Editar el crontab del usuario root.
```bash
crontab -e
```
Añadir las dos siguientes líneas al final para actualizar regularmente la lista blanca.
```bash
@daily /usr/local/bin/postwhite/postwhite > /dev/null 2>&1 #Actualizar las listas blancas de Postscreen
@weekly /usr/local/bin/postwhite/scrape_yahoo > /dev/null 2>&1 #Update Yahoo! IPs para las listas blancas de Postscreen
```
Guardar y cerrar el archivo. Ahora, si se envía un correo electrónico desde Gmail a la dirección de correo del dominio, y se comprueba el registro de correo, se verá que Postscreen no realiza ninguna prueba, porque la dirección IP está en la lista blanca.
```bash
Feb 10 13:04:17 mail postfix/postscreen[24895]: CONNECT from [209.85.166.44]:38257 to [23.254.225.226]:25
Feb 10 13:04:17 mail postfix/postscreen[24895]: WHITELISTED [209.85.166.44]:38257
Feb 10 13:04:17 mail postfix/smtpd[26596]: connect from mail-io1-f44.google.com[209.85.166.44]
```
## Postfix – Colas de mensajes
Cuando un correo electrónico no se envía, termina en una de las dos colas dentro de Postfix: pending (pendiente) y deferred (diferido).
La cola de pendientes incluye todos los mensajes que has enviado a Postfix que aún no han sido enviados y entregados al servidor del destinatario. La cola de correo diferido contiene todos los mensajes que han fallado y se necesita reintentar enviarlos (fallo temporal).
Postfix intentará reenviar los mensajes de la cola diferida a intervalos establecidos. Esto está configurado a 5 minutos de manera predeterminada, pero este proceso es totalmente configurable.
Introduciendo cualquiera de los siguientes comandos, puedes inspeccionar y gestionar tus colas de mensajes de Postfix con facilidad.
### Cómo revisar las colas de mensajes de Postfix
1) Visualizar las colas de correo: diferido y pendiente
```bash
# mailq
```
ó
```bash
# postqueue -p
```
Alternativamente, para guardar la salida en un archivo de texto, ejecuta
```bash
# mailq > mailqueue.txt
```
ó
```bash
# postqueue -p > mailqueue.txt
```
Cualquiera de estos comandos mostrará el remitente, los destinatarios y el ID, pero no el mensaje en sí. Aunque el ID ayudará a localizar los mensajes individuales.
**Ver el mensaje (contenido, cabecera y cuerpo) en la cola de Postfix**
Los ID de los mensajes están disponibles en la cola de mensajes. Así que, para ver un mensaje con el ID XXXXXXX, ingresar
```bash
# postcat -vq XXXXXXXXXX
```
O, para guardarlo en un archivo, introducír
```bash
# postcat -vq XXXXXXXXXX > emailXXXXXXXX.txt
```
Una característica útil para los servidores web es habilitar _mail.add_x_header = on_ en la configuración de Postfix.
Esto añadirá una cabecera a todos los mensajes de correo electrónico salientes mostrando el script y el usuario que generó cada mensaje. Una vez habilitado esto añadirá la siguiente cabecera extra al mensaje:
```bash
X-PHP-Originating-Script: 1001:spamEmailer.php
```
En este ejemplo, 1001 es el ID del usuario y spamEmailer.php es el script que envía el mensaje. Esto permite rastrear rápidamente el origen de cualquier mensaje de spam enviado desde nuestro servidor.
Monitoreo de la cola en tiempo real
```bash
# watch -n1 mailq
```
Para filtrar la salida con grep es necesario especificar el comando entre comillas
```bash
# watch 'mailq | grep "[^A-F0-9]"'
```
### Cómo eliminar el correo en cola de espera
**Forzar el procesamiento de la cola**
```bash
# postqueue -f
```
ó
```bash
# postfix flush
```
**Eliminar el correo en cola**
Un comando permite eliminar todos los mensajes en cola en Postfix. Esto incluye los mensajes de las pending (pendiente) y deferred (diferido):
```bash
# postsuper -d ALL
```
Para borrar específicamente todos los mensajes de la cola diferida (es decir, sólo los que el sistema pretende reintentar más tarde), ingresá
```bash
# postsuper -d ALL deferred
```
**Eliminar selectivamente el correo de la cola**
También se pueden eliminar mensajes específicos de la cola de correo. Esto no es algo que esté incluido de forma nativa con las herramientas estándar de Postfix, pero (gracias a que usamos software libre) existe una solución para ello.
Así, para eliminar todos los mensajes de la cola de correo enviados por o a usuario@ejemplo.com (el comando es el mismo independientemente de si se trata de la dirección del remitente o del destinatario), se puede utilizar este comando:
```bash
# mailq | tail +2 | awk 'BEGIN { RS = "" } / usuario@ejemplo\.com$/ { print $1 }' | tr -d '*!' | postsuper -d -
```
ó
```bash
# postqueue -p | tail -n +2 | awk 'BEGIN { RS = "" } /@dominio\.com/ { print $1 }' | tr -d '*!' | postsuper -d -
```
## Análisis de LOGs
Pflogsumm crea un análisis/resumen de los registros para de Postfix. Está diseñado para proporcionar una visión general de la actividad de Postfix, con el suficiente detalle para dar al administrador un “aviso” de los posibles puntos problemáticos.
Pflogsumm genera resúmenes y, en algunos casos, informes detallados de de los volúmenes de tráfico del servidor de correo, el correo electrónico rechazado y rebotado, y las advertencias, errores y pánicos del servidor. advertencias, errores del servidor.
Se encuentra disponible en los repositorios de Debian, así que su instalación es sencilla.
```bash
# apt install -y pflogsumm
```
Ejemplos de comandos para generar reportes:
para hoy
```bash
pflogsumm -d today /var/log/mail.log
```
para ayer
```bash
pflogsumm -d yesterday /var/log/mail.log
```
para esta semana
```bash
pflogsumm /var/log/mail.log
```
Para emitir informes de “problemas” (rebotes, diferidos, advertencias, rechazos) antes de las estadísticas “normales”, usar el parámetro –problems-first.
```bash
pflogsumm -d today /var/log/mail.log --problems-first
```
Para añadir la dirección de correo electrónico de origen a cada informe de rechazo, utilizar el parámetro –rej-add-from.
```bash
pflogsumm -d today /var/log/mail.log --rej-add-from
```
Para mostrar el detalle completo en los resúmenes de rechazo, usar el parámetro –verbose-msg-detail.
```bash
pflogsumm -d today /var/log/mail.log --rej-add-from --verbose-msg-detail
```
Se puede añadir una tarea cron para que pflogsumm envíe un informe a una dirección de correo electrónico cada día.
```bash
crontab -e
```
Agregar la siguiente línea, que generará un informe cada día a las 4:00 AM.
```bash
0 4 * * * /usr/sbin/pflogsumm -d yesterday /var/log/mail.log --problems-first --rej-add-from --verbose-msg-detail -q
```
Para recibir el informe por correo electrónico, añadir la siguiente línea por encima de todas las tareas cron.
```bash
MAILTO="casilla@dominio.edu.ar"
```
Se debe prestar atención a la sección de detalles de los mensajes rechazados, para ver por qué razón se rechazan esos correos electrónicos y si hay algún falso positivo.
En caso de preferir una interfaz gráfica se puede optar por instalar Lightmeter, una herramienta basada en web, cuya instalación se describe en [monitoreo de servidor de correo con lightmeter](https://informatica.unau.edu.ar/monitoreo-de-servidor-de-correo-con-lightmeter/).
## Depuración y seguimiento en Postfix
Una característica muy buena que tiene Postfix es la capacidad de depurar hosts individuales específicos. Sólo hay que añadir esto al main.cf:
```bash
# Depurar hosts individuales
debug_peer_level=3
debug_peer_list=regexp:/etc/postfix/debug_peers
```
El nivel predeterminado es 2. En el caso del ejemplo estamos usando un archivo de mapeo, pero no es estrictamente necesario. Basta con ingresar valores separados por coma:
```bash
debug_peer_list=170.0.131.2,ejemplo.edu.ar
```
Utilizando regex podemos capturar múltiples IPs y dominios similares. Este es un ejemplo:
```bash
# Esta es una lista disimulada como un hash clave-valor.
# Los campos de la derecha sólo son útiles para las pruebas.
# Por alguna extraña razón, el regex de Postfix no soporta
# el parámetro "\d": /185\.234\.219\d{1,3}/ A
/170\.0\.131\.[0-9]{1,3}/ A
/[0-9]{4}.com/ B
/139\.176\.255\.106/ C
```
Es necesario tener en cuenta que esto es sólo un listado y no un mapa real, pero Postfix utiliza el mismo código de análisis para estos por lo que hay que presentar como un archivo de mapeo. Así que los campos de la derecha (A, B y C) – no significan nada. Son sólo marcadores de posición. Pero son útiles para probar los patrones de coincidencia.
Por supuesto, cuando se configura el archivo de mapeo resulta necesario procesarlo con postmap:
```bash
postmap debug_peers
```
Para evitar recibir errores al procesar el archivo de mapeo hay que ingresar valores con una descripción al lado, por ejemplo:
```bash
lists.isc.org #Listas de Correo de la ISC
```
También se puede ejecutar “postmap -q” para probar el mapeo:
```bash
postmap -q "170.0.131.2" regexp:debug_peers
```
Esto es especialmente útil con regex, ya que a veces el regex es un poco desordenado. De esta manera, podemos cerciorarnos que el mapeo está configurado como queremos.
Además de regex – se puede hacer un hash directo que es sólo un mapa de pares clave-valor; se puede hacer pcre que es como la versión Perl de regex; y se puede hacer CIDR. Al ejecutar el comando “postconf -m”, mostrará con qué se compiló Postfix (el tipo de mapas) que podemos utilizar:
```bash
# postconf -m
btree
cidr
environ
fail
hash
inline
internal
memcache
nis
pipemap
proxy
randmap
regexp
socketmap
sqlite
static
tcp
texthash
unionmap
unix
```
### Verbosidad
También se puede configurar la verbosidad en todo el servicio SMTP de Postfix simplemente añadiendo un “-v” en el archivo master.cf:
```bash
smtp inet n - y - - smtpd -v
```
Luego recargamos Postfix
```bash
# systemctl reload postfix
```
Veremos grandes cantidades de datos, pero podría ser bastante útil a veces. Se puede hacer lo mismo para otros procesos esclavos de Postfix.
Para más detalles recomendamos revisar los [documentos de depuración de Postfix](http://www.postfix.org/DEBUG_README.html).
## Herramientas de Análisis
* [https://www.mail-tester.com/](https://www.mail-tester.com/)
* [https://www.dmarcanalyzer.com/](https://www.dmarcanalyzer.com/)
* [https://mxtoolbox.com/](https://mxtoolbox.com/)
* [https://dkimcore.org/](https://dkimcore.org/)
* [https://www.immuniweb.com/ssl/](https://www.immuniweb.com/ssl/)
* [https://ssl-tools.net/mailservers](https://ssl-tools.net/mailservers)