Table of Contents
Instalación de un servidor de correo
Vamos a ver cómo configurar un servidor de correo en linux. Tendremos las siguientes funcionalidades:
- Servidor de correo IMAP con dovecot por SSL
- Servidor SMTP con postfix por TLS mediante STARTTLS
- Gestión de usuarios y dominios virtuales vía web mediante aplicación vmail.
- Aplicación de webmail mediante Roundcubemail
- Filtros de mensajes
- Respuesta automática
- Filtro anti-spam
- y alguna cosa más.
Vamos a asumir que el host se llama vmail.
Base de datos
Si no está instalado, hay que instalar
apt install mariadb-server
Luego, entrar en el servidor, crear la base de datos y dar permisos
root@vmail:~# mariadb Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 5851 Server version: 10.11.14-MariaDB-0+deb12u2 Debian 12 Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> create database vmail; Query OK, 1 row affected (0,000 sec) MariaDB [(none)]> GRANT ALL ON vmail.* TO 'vmail'@'localhost' IDENTIFIED BY 'vmail'; Query OK, 1 row affected (0,000 sec) MariaDB [(none)]> flush privileges; Query OK, 1 row affected (0,000 sec) MariaDB [(none)]> exit Bye root@vmail:~#
Instalación del software vmail
Vamos a instalar la aplicación web Vmail. Corre bajo nginx, y necesita php y una base de datos (que acabamos de crear). En primer lugar, vamos a hacerlo en un entorno debian 12 (bookworm), que no tiene diferencias para luego hacerlo en debian 13 (trixie). Instalamos:
- git
- php-cli y las extensiones php requeridas por symfony, como php-mysql
- php-fpm
- nginx
- vhost generator para generar los vhosts
root@vmail:~# apt install git php-cli php-fpm php-mysql nginx php-xml php-curl curl Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: git-man liberror-perl libsodium23 patch php-common php8.2-cli php8.2-common php8.2-fpm php8.2-mysql php8.2-opcache php8.2-readline psmisc nginx nginx-common libxslt1.1 php8.2-xml libcurl4 php8.2-curl
Creamos el usuario vmail, con uid y gid 5000, así como los directorios necesarios para la aplicación:
root@vmail:~# useradd -u 5000 -m -s /bin/bash vmail root@vmail:~# adduser www-data vmail root@vmail:~# mkdir -p /var/lib/vmail root@vmail:~# chown vmail:vmail /var/lib/vmail
Configurar nginx
Vamos a usar http, por hacerlo fácil en este punto y porque no tenemos certificados (aunque se podría usar el snake-oil).
root@vmail:~# cd /etc/nginx root@vmail:/etc/nginx# rm sites-enabled/default root@vmail:/etc/nginx# git clone https://github.com/omgslinux/nginx-vhost-generator vhost-generator root@vmail:/etc/nginx# cd vhost-generator root@vmail:/etc/nginx/vhost-generator# cp defaults.inc_dist defaults.inc # Editar el fichero defaults.inc y poner el sufijo predeterminado en SUFFIX, etc. root@vmail:/etc/nginx/vhost-generator# mkdir vmail root@vmail:/etc/nginx/vhost-generator# cat > vmail/vmail.inc <<EOF VHOST_TYPE="symfony" SERVER="vmail" DOCROOT="/home/vmail/\$SERVER/public" HTTP_PORT="80" HTTP_ENV="prod" #HTTPS_PORT="8080" #HTTPS_ENV="prod" unset SSL_CERTIFICATE SSLCLIENT_FASTCGI="" FASTCGI_PASS="unix:/run/php/vmail-fpm.sock" EOF # Ya que estamos, preparamos la configuración para roundcube root@vmail:/etc/nginx/vhost-generator# mkdir roundcube cat > roundcube/roundcube.inc <<EOF VHOST_TYPE="php" SERVER="roundcube" DOCROOT="/var/www/vhosts/\$SERVER/public_html" HTTP_PORT="80" unset SSL_CERTIFICATE SSLCLIENT_FASTCGI="" EOF root@vmail:/etc/nginx/vhost-generator# ./mkvhost.sh vmail roundcube root@vmail:/etc/nginx/vhost-generator# nginx -t && service nginx restart root@vmail:/etc/nginx/vhost-generator# cd root@vmail:~#
Instalación de composer
Necesitamos instalar composer para configurar la aplicación vmail:
root@vmail:~# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
root@vmail:~# php composer-setup.php --install-dir=/usr/local/bin --filename=composer
root@vmail:~# php -r "unlink('composer-setup.php');"
Configurar php-fpm
Necesitamos crear una configuración especial con el usuario vmail, por permisos de escritura. Para ello, clonamos el pool predeterminado y modificamos los valores mínimos para su funcionamiento, además de poner el fichero .sock en un lugar específico, según la configuración previa en el vhost de nginx:
root@vmail:~# PHP_VER=$(php -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;") root@vmail:~# cp /etc/php/$PHP_VER/fpm/pool.d/www.conf /etc/php/$PHP_VER/fpm/pool.d/vmail.conf root@vmail:~# sed -i 's/\[www\]/\[vmail\]/' /etc/php/$PHP_VER/fpm/pool.d/vmail.conf root@vmail:~# sed -i 's/www-data/vmail/g' /etc/php/$PHP_VER/fpm/pool.d/vmail.conf root@vmail:~# sed -i "s|^listen =.*|listen = /run/php/vmail-fpm.sock|" /etc/php/$PHP_VER/fpm/pool.d/vmail.conf root@vmail:~# systemctl restart php$PHP_VER-fpm # Si tenemos mariadb/mysql en un servidor diferente, añadimos su nombre e ip al fichero hosts, para usar 'mysql' como nombre de servidor. root@vmail:~# echo "192.168.12.100 mysql">>/etc/hosts
Configuración con el usuario vmail
En los siguientes pasos, vamos a usar el usuario no privilegiado vmail que hemos creado para usar la aplicación y los directorios de correo.
root@vmail:~# su - vmail vmail@vmail:~$ git clone https://github.com/omgslinux/vmail.git vmail@vmail:~$ cd vmail vmail@vmail:~/vmail$ echo 'APP_ENV=prod vmail@vmail:~/vmail$ DATABASE_URL="mysql://vmail:vmail@mysql:3306/vmail?serverVersion=11.8.3-MariaDB&charset=utf8mb4"'>>.env # Si tenemos el servidor mysql en localhost u otro, editar el fichero .env y modificar '@mysql:3306' por lo que proceda. vmail@vmail:~/vmail$ composer install vmail@vmail:~/vmail$ bin/console asset-map:compile vmail@vmail:~/vmail$ bin/console doctrine:schema:update --force vmail@vmail:~/vmail$ bin/console vmail:setup
En este último paso, nos muestra por pantalla las credenciales para poder entrar en la aplicación. En este instante, deberíamos poder entrar por http al vhost configurado en nginx, http://vmail.dominio.com, que si no está en el DNS, habrá que añadir una línea en el fichero /etc/hosts que apunte a la ip correspondiente.
Con la aplicación, ahora es el momento de crear el dominio y los usuarios de correo, que probaremos luego con dovecot primero y después con postfix.
DKIM
Si tenemos un dominio (que es lo normal para el correo), y queremos que el correo enviado no vaya a spam, una medida es instalar soporte DKIM. Esto hace que los correos salientes lleven una firma que puede identificar que el correo sale del servidor de correo del dominio y no de una fuente cualquiera.
apt install opendkim opendkim-tools
En una configuración muy básica, tenemos que mirar que el fichero /etc/opendkim.conf contenga estas líneas:
UserID opendkim:opendkim Socket local:/run/opendkim/opendkim.sock KeyTable /etc/opendkim/KeyTable SigningTable /etc/opendkim/SigningTable
Socket, que habrá que copiar tal cual está en postfix
El objetivo es tener una estructura como ésta:
/etc/dkimkeys/
├── KeyTable
├── SigningTable
└── dominio.com/
├── mail.private
└── mail.txt
Ahora se puede crear una clave
root@vmail:/etc/dkimkeys# mkdir dominio.com
root@vmail:/etc/dkimkeys# opendkim-genkey -s mail -d dominio.com -D dominio.com
root@vmail:/etc/dkimkeys# cat dominio.com/mail.txt
mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArLGJuK6LNeE0CUW76tzJGSVRy/Wi3BEQUD4N70C3cyLkuCvzKB/QWqgOdNCdJacCs513kA+rDyShIvzADRhRWtjw+kSUf/JOhWcHF7H5aYW3nFxX8S/AquAmKE2UDYsTzycL/0DkFL51PD5MHL3sHpXNv/lGnQ
nOifH9Vzyd+Bv+CKbrkypxDPHwuUPZ2FOLnXt57fv93DBAsT"
"2ej7VBTGCNUlH4ePH6cdLr0LORg1YX9qn0YvDr2uyT/0MxDUgDBcNoTEDXMPYegQg7fij5hYnaviefxPig99QIvTqxT7CkacshtyeQKtwaO+OISYb3pFm2kAcpBBo9G55ZPNrTjQIDAQAB" ) ; ----- DKIM key mail for dominio.com
Eso quiere decir que habría que crear un registro TXT en el DNS de dominio.com bajo la clave mail._domainkey con el contenido desde "v=DKIM1; ..." hasta "DAQAB".
TXT debe incluir también las comillas dobles de apertura y cierre
Después, el fichero /etc/dkimkeys/KeyTable debe tener una línea por dominio con este formato:
mail._domainkey.dominio.com dominio.com:mail:/etc/dkimkeys/dominio.com/mail.private
De manera similar, el fichero /etc/dkimkeys/SigningTable debe tener una línea por dominio con este formato:
*@dominio.com mail._domainkey.dominio.com
Finalmente, nos aseguramos de que todos los ficheros tienen los permisos adecuados:
root@vmail:~# chown -R opendkim:opendkim /etc/dkimkeys root@vmail:~# chmod -R og-rwx /etc/dkimkeys
Luego, una forma de comprobar si todo está correcto, es enviar un correo a check-auth@verifier.port25.com, donde se devuelve un informe con los detalles.
Dovecot y Postfix
Vamos a instalar el software necesario:
- snippet.bash
IMAP="dovecot-core dovecot-mysql dovecot-imapd dovecot-sieve dovecot-lmtpd dovecot-managesieved $SQLSERVER" SMTP="postfix-mysql" ANTISPAM="amavisd-new" apt install -y $IMAP $SMTP $ANTISPAM
Una vez instalado, ejecutamos como usuario root unos comandos de la aplicación vmail preparados para configurar todos los servicios relacionados.
root@vmail:~# cd /home/vmail/vmail root@vmail:/home/vmail/vmail# bin/console app:dovecot:conf root@vmail:/home/vmail/vmail# bin/console app:postfix:conf
Verificamos varias cosas:
- Tener en
/etc/dovecot/private/los certificados adecuados. Por defecto, se usa el desnake-oil. - Si se usa DKIM, que el resultado de
postconf smtpd_milterscoincide con la línea descomentada deSocketen el fichero/etc/opendkim.conf. En el caso de ser un fichero y no un socket tcp, habrá que añadir al usuario de postfix al grupo:adduser postfix opendkim. - Que tanto
dovecot -ncomopostfix checkno dan errores fatales. Revisar en todo caso los mensajes que puedan surgir. - Que el servicio
amavisestá funcionando correctamente. En ocasiones, hay que indicarle de forma explícita un hostname en/etc/amavis/conf.d/05-domain_id.
Después, reiniciamos los servicios:
service opendkim restartservice dovecot restartservice postfix restart- Con
ss -puntaverificamos los puertos IMAP (993, si acaso 143), SMTP (25 y 587), el DKIM (sock o puerto 8891) y amavis (puerto 10024).
Partiendo de la base de haber creado antes un usuario xxx en el dominio dominio.com, usamos la utilidad doveadm para realizar comprobaciones básicas desde la línea de comandos. Vamos a hacer dos:
1) Devolución de los parámetros de usuario:
# doveadm user xxx@dominio.com field value uid 5000 gid 5000 home /var/lib/vmail/dominio.com/xxx mail maildir:~/Maildir quota_rule *:storage=0B
2) Autenticación del usuario (nos pide password):
# doveadm auth test xxx@dominio.com Password: passdb: xxx@dominio.com auth succeeded extra fields: user=xxx@dominio.com
3) Ubicación del INBOX:
# doveadm mailbox path -u xxx@dominio.com INBOX /var/lib/vmail/dominio.com/xxx/Maildir
Tiene que devolver la ruta home de 1) con Maildir agregado al final.
Roundcubemail
Cuando todo esté correcto, podremos hacer pruebas de recepción y envío, pero vamos a instalar Roundcubemail. Vamos a usar la versión 1.6.12, que es la LTS:
RVERSION="1.6.12" mkdir -p /var/www/vhosts cd /var/www/vhosts wget https://github.com/roundcube/roundcubemail/releases/download/${RVERSION}/roundcubemail-${RVERSION}-complete.tar.gz tar zxf roundcubemail-${RVERSION}-complete.tar.gz ln -s roundcubemail-${RVERSION} roundcube chown -R www-data:www-data roundcubemail-${RVERSION} pushd roundcube/public_html ln -s ../installer popd
Antes de nada, hay que crear una base de datos específica y un usuario en la base de datos. Repetir los pasos necesarios igual que se hizo al principio para la aplicación vmail.
Una vez hecho esto, y como ya preparamos nginx en su momento, podemos ir a http://roundcube.dominio.com/installer, para iniciar la instalación. Seguimos los pasos del instalador y hacemos los pasos del instalador.
Si hay un certificado autofirmado, antes de proceder a probar la recepción en el instalador, se puede añadir lo siguiente al final del archivo /var/www/vhosts/roundcube/config/config.inc.php:
$config['imap_conn_options'] = $config['smtp_conn_options'] = [ 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true, ], ];
Una vez pasadas las pruebas, se deshabilita el instalador con
$config['enable_installer'] = false;
Una vez instalado, podemos realizar pruebas de envío y recepción con varios usuarios simultáneos a través de la interfaz web.
