Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Hoy vamos a dejar por aquí un paso a paso para montar un servidor de correo de la forma más
sencilla posible y con acceso a través de IMAP y de webmail. Partimos, para ello, de un servidor
Debian recien instalado y disponemos de un dominio y de un servicio desde el que gestionar los
registros de nuestro DNS. Para la instalación usaremos Postfix como SMTP, Dovecot como
servidor IMAP y Squirrel como servicio de Webmail.
Lo primero que debemos de hacer es planificar los nombres que necesitamos dar de alta en el
DNS para hacerlo cuanto antes y dar tiempo a que se propaguen. Realmente un único registro A
y otro MX nos valdrían ya que todo va a funcionar en la misma máquina, pero por aquello de que
quede bonito y pensando en futuros cambios en los que el servicio crezca y necesitemos usar
máquinas diferentes para cada cosa, deberíamos de crear un registro A diferente para cada uno
de los servicios. Algo así:
smtp IN A 99.99.99.99
mail IN A 99.99.99.99
webmail IN A 99.99.99.99
@ IN MX 10 mail.midominio.com
Donde, lógicamente, hemos de cambiar midominio.com por el nombre de dominio que vamos a
usar y 99.99.99.99 por la IP de nuestra máquina.
En segundo lugar debemos de instalar los paquetes que necesitamos. Dejaremos el webmail
para el final y nos centraremos en el resto. Para ponerlo en funcionamiento necesitamos
instalar, además de postfix y dovecot, los paquetes necesarios para realizar la autenticación
mediante el protocolo SASL:
# apt-get install postfix-tls libsasl2-2 sasl2-bin libsasl2-modules
dovecot-imapd
En la primera línea debemos de sustituir la cadena en negritas por el dominio cuyo correo
queremos recibir. El resto de los parámetros determinan el tipo de autenticación que vamos a
realizar, el servicio que se encargará de la autenticación (dovecot en este caso) y las
restricciones de acceso más comunes al servidor. Tienes información detallada de todas ellas en
este enlace.
Con el parámetro home_mailbox, muy importante, indicamos a Postfix que queremos usar el
formato de correo Maildir y que la ubicación de las carpetas donde se almacenará este será un
directorio denominado Maildir en el raiz del directorio home de cada usuario. Si no lo
especificamos así, el correo se almacenará en un único fichero con el nombre de la cuenta de
cada usuario y bajo el directorio /var/mail.
Una de las operaciones que se realiza durante la instalación de Dovecot es crear la estructura
necesaria para albergar los buzones de correo en el directorio /etc/skel que es el que sirve de
plantilla para generar el home de los nuevos usuarios. Eso quiere decir que los usuarios que
tengamos previamente creados antes de hacer esta instalación no dispondrán de dichos
directorios y, por tanto, no funcionaran correctamente. Para remedir esto tenemos que copiar
manualmente dicha estructura. Supongamos que queremos copiar la estructura de buzones al
usuario josemaria, ya creado antes de esta instalación. La operación sería la siguiente:
# cp -r /etc/skel/Maildir /home/josemaria
# chown -R josemaria:josemaria /home/josemaria/Maildir
# chmod -R 700 /home/josemaria/Maildir
El siguiente cambio va encaminado a configurar el identificador único que usaremos para cada
email. Para que exista compatibilidad con algunos de los clientes de Microsoft es necesario que
se defina de esta forma:
pop3_uidl_format = %08Xu%08Xv
Y ya sólo nos resta por definir los parámetros relativos al mecanismo de autenticación que
hemos elegido. Lo hacemos con el siguiente bloque:
auth default {
mechanisms = plain login
passdb pam {
}
userdb passwd {
}
socket listen {
client {
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
}
Ahora necesitamos hacer unas pequeñas modificaciones para permitir la comunicación entre
postfix y sasl. Puesto que el daemon de postix se ejecuta mediante chroot en el directorio
/var/spool/postfix, crearemos un enlace allí al que podrá acceder el daemon de sasl:
# mkdir -p /var/spool/postfix/var/run/saslauthd
# rm -r /var/run/saslauthd/
# ln -s /var/spool/postfix/var/run/saslauthd /var/run
# chgrp sasl /var/spool/postfix/var/run/saslauthd
# adduser postfix sasl
Y, finalmente, debemos de reiniciar los tres servicios involucrados para que lean los cambios
hechos en sus respectivas configuraciones:
#/etc/init.d/saslauthd restart
#/etc/init.d/postfix restart
#/etc/init.d/dovecot restart
Para quién la autenticación mediante usuario y contraseña con texto plano se le quede corta,
puede echarle un vistazo a este tutorial donde explican como realizarla mediante TLS.
Vamos ahora con la instalación de Squirrel Mail que es mucho más sencilla. Para ello
necesitamos instalar apache, php y el propio squirrel:
# apt-get install apache2 libapache2-mod-php5 php5-cli php5-common php5-
cgi squirrelmail
Y, por último, habilitamos el sitio y pedimos a Apache que vuelva a recargar su configuración:
# a2ensite squirrelmail
# /etc/init.d/apache2 reload
Otro posible “extra” sería permitir que los usuarios con cuenta de correo pudieran modificar sus
contraseñas a través de la web. En Unixcraft nos cuentan como hacer un script PHP para
permitirlo.
If you just wanted to change your own password or other user passwords use passwd
command.
I was asked to setup a PHP based interface to change the password. Since my knowledge of
php is limited. Here is what I did:
Required tools/setup:
#!/bin/sh
# \
exec expect -f "$0" ${1+"$@"}
set password [lindex $argv 1]
spawn passwd [lindex $argv 0]
sleep 1
expect "assword:"
send "$password\r"
expect "assword:"
send "$password\r"
expect eof
Download script and copy to your webroot or location where webserver can read this script
file:
$ cp chpasswd /var/www/
Apache or Lighttpd web server drops root privileges as soon as they go into background.
This makes changing password scenario difficult as passwd command needs root privileges
to change other user account password.
Typically, Apache 2 use www-data user and Lighttpd use lighttppd username to drop
privileges. Login as root user and type the following command:
# visudo
Now allow your web server to execute a script (chpasswd) w/o password. If you are using
Apache web server, type the following command:
www-data ALL=NOPASSWD: /var/www/chpasswd
ALTERNATIVELY, if you are using Ligtttpd web server, type the following command:
lighttpd ALL=NOPASSWD: /home/lighttpd/chpasswd
Now you need to write a php script. Here is sample php script. This is a demo script. You
should modify it according to your requirement or setup. At minimum, you need to setup
correct shell script location so that it will work for you out of box. Open php script and
locate line:
$shellscript = "sudo /home/lighttpd/chpasswd";
<?php
// change .. me! - shell script name
$shellscript = "sudo /home/lighttpd/chpasswd";
';
echo '
System returned following information:
';
print_r($output);
echo '
';
writeFoot();
}
}
else {
writeHead("Something was wrong -- Please try again");
echo 'Error - Please enter username and password';
writeForm();
writeFoot();
}
}
.passwdleft {
width: 25%;
text-align: right;
clear: both;
float: left;
display: inline;
padding: 4px;
margin: 5px 0;
}
.passwdright {
width: 70%;
text-align: left;
float: right;
display: inline;
padding: 4px;
margin: 5px 0;
}
.passwderror {
border: 1px solid #ff0000;
}
.passwdsubmit {
}
</style>
</head>
<body>';
}
// display html form
function writeForm() {
echo '
<h3>Use following form to change password:</h3>
<script>
function checkForm() {
if (document.forms.changepassword.elements[\'username\'].value.length ==
0) {
alert(\'Please enter a value for the "User name" field\');
return false;
}
if (document.forms.changepassword.elements[\'passwd\'].value.length == 0)
{
alert(\'Please enter a value for the "Password" field\');
return false;
}
return true;
}
</script>
<div class="contactform">
<form action="' . $_SERVER[PHP_SELF]. '" method="post" onSubmit="return
checkForm()" name="changepassword">
<div class="passwdleft"><label for="lblusername">User Name:
</label></div>
<div class="passwdright">
<input type="text" name="username" id="lblusername" size="30"
maxlength="50" value="" /> (required)</div>
<div class="passwdleft"><label for="lblpasswd">Password: </label></div>
<div class="passwdright">
<input type="password" name="passwd" id="lblpasswd" size="30"
maxlength="50" value="" /> (required)</div>
<div class="passwdright">
<input type="submit" name="Submit" value="Change password"
id="passwdsubmit" />
<input type="hidden" name="pwdchange" value="process" /></div>
</form>
</div>
';
}
// display footer
function writeFoot(){
echo '</body>
</html>
';
}
?>
For some reason if a password failed to change, you should get detailed error message as
follows:
Step # 5: Security
• Never ever run this script over http session. Always run over https session.
• Put script in a password protected directory (see how to setup Apache or Lighttpd
web server password protected directory).
• Never ever, trust user input. Above php script is just a sample, for real life
production you should consider more powerful user input validation. Discussion
regarding PHP programming security is beyond the scope of this article. You can
consult a good PHP book or search a web using your favorite search engine :)