--- 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)