Problemas de postgrey y las listas grises con los servidores de correo de outlook y hotmail de Microsoft

correo Hace ya años que contamos por aquí en que consisten las listas grises a la hora de validar como bueno un correo y combatir contra el spam y enseñamos a configurarlas en un servidor con Debian y postfix. Recientemente he tenido muchos problemas con los correos que vienen de servidores de Microsoft (¡como no!) que provocaban retrasos de hasta algunos días o pérdida de correos en algunas ocasiones. Vamos a contar que es lo que ocurre y como solucionarlo.

El problema que tenemos con los servidores de correo de Microsoft es que el reintento de envío del correo que exige el sistema de listas grises no se realiza desde el mismo servidor que realiza el envío original con lo que nuestro sevidor toma el reintento como un correo diferente al original y no lo valida como correcto. La solución es fácil y seguramente estará “parcheada” en un futuro en nuestras Debian, pero por el momento tienes que solucionarla por ti mismo. Vamos a verlo.

En el directorio /etc/postgrey tenemos dos ficheros: whitelist_clients y whitelist_recipients. En ellos podemos incluir manualmente los servidores y direcciones de correo (respectivamente) que queremos validar automáticamente sin pasar por el sistema de listas grises. No obstante, hacerlo es una mala idea: en estos ficheros (sobre todo en el primero) es donde los mantenedores de Debian incluyen los servidores de correo que ya saben que dan problemas con el sistema de listas grises pero son servidores válidos. Posiblemente nuestro problema se resolverá en un futuro próximo cuando la gente de Debian incluya los servidores de Microsoft en este fichero pero mientras tanto tenemos que buscarnos una solución. Postgrey admite incluir en este mismo directorio dos nuevos ficheros con la misma funcionalidad pero donde podamos incluir nuestros propios servidores y direcciones de correo sin miedo a perder actualizaciones: whitelist_clients.local y whitelist_recipients.local.

Ahora ya sólo nos hace falta saber cuales son las direcciones de los servidores de correo de Microsoft. Afortunadamente están casi todas publicadas aquí. En algún foro he leído que es interesante añadir un par de líneas adicionales para validar los servidores de los servidores de Office 365. Al final, mi fichero whitelist_clients.local ha quedado así:

23.103.132.0/22
23.103.136.0/21
23.103.144.0/20
23.103.156.0/22
23.103.191.0/24
23.103.198.0/23
23.103.198.0/24
23.103.199.0/24
23.103.200.0/22
23.103.212.0/22
40.92.0.0/14
40.107.0.0/17
40.107.128.0/18
52.100.0.0/14
65.55.88.0/24
65.55.169.0/24
94.245.120.64/26
104.47.0.0/17
104.212.58.0/23
134.170.132.0/24
134.170.140.0/24
157.55.234.0/24
157.56.110.0/23
157.56.112.0/24
207.46.51.64/26
207.46.100.0/24
207.46.163.0/24
213.199.154.0/24
213.199.180.128/26
216.32.180.0/23
2a01:111:f400:7c00::/54
2a01:111:f403::/48
104.47.0.0/17
40.107.0.0/16
/.*outbound.protection.outlook.com$/
/outlook/

Ahora sólo queda reiniciar los daemons de postgrey y postfix para que los cambios tomen efecto y listo

Chuletillas (y XXXXVII) – Instalar un programa de debian Stretch mientras que usas debian stable (Jessie)

chuletaSi quieres instalar un determinado programa (y sus dependencias obligatorias) incluido en la próxima versión de Debian (Stretch) mientras continuas usando la versión stable (Jessie) puedes hacerlo de la siguiente forma:

En primer lugar edita tu fichero sources.list (en el directorio /etc/apt) e incluye al final las direcciones de los repositorios de Stretch pero sin eliminar ni modificar los que ya usas de Jessie. Por ejemplo así:

# Repositorios de Jessie
deb http://http.debian.net/debian/ jessie main contrib non-free
deb-src http://http.debian.net/debian/ jessie main contrib non-free
deb http://security.debian.org/ jessie/updates main contrib non-free
deb-src http://security.debian.org/ jessie/updates main contrib non-free

# Updates de Jessie, antes conocidos como 'volatile'
deb http://http.debian.net/debian/ jessie-updates main contrib non-free
deb-src http://http.debian.net/debian/ jessie-updates main contrib non-free

# Backports de Jessie
deb http://http.debian.net/debian jessie-backports main contrib non-free

#Repositorios de Stretch
deb http://http.debian.net/debian/ stretch main contrib non-free
deb-src http://http.debian.net/debian/ stretch main contrib non-free
deb http://security.debian.org/ stretch/updates main contrib non-free
deb-src http://security.debian.org/ stretch/updates main contrib non-free

# Updates de Stretch
deb http://http.debian.net/debian/ stretch-updates main contrib non-free
deb-src http://http.debian.net/debian/ stretch-updates main contrib non-free

A continuación creamos un fichero llamado stretch en el directorio /etc/apt/preferences.d y escribimos en el lo siguiente:

Package: *
Pin: release n=jessie
Pin-Priority: 900

Package: *
Pin: release n=stretch
Pin-Priority: 100

Con esto estamos modificando la prioridad con la que Debian actualizará nuestros paquetes. Por defecto instala siempre la versión más moderna de todas las que tenga disponibles en sus repositorios. Con este fichero le dará preferencia a cualquier paquete de jessie frente a uno de stretch aunque tenga una versión menor. Es decir, mantendremos nuestro sistema con las versiones de jessie salvo que un paquete no exista en esta y si en stretch… O se lo indiquemos manualmente durante la instalación que es lo que vamos a ver a continuación. Si quieres maś información sobre la forma de establecer preferencia para apt puedes echarle un vistazo a esta página.

Y ya lo tenemos todo listo. Ahora, tenemos que actualizar nuestros repositorios (apt update) y cuando queramos instalar un paquete directamente de stretch lo especificamos manualmente en el comando apt. Por ejemplo, si quisiéramos instalar la versión de apache de stretch lo haríamos así:

apt-get install -t stretch apache2

Cambios en la configuración de nginx y php5-fpm en Debian 8 (Jessie)

nginx Hace unos días, tras actualizar la versión de Debian a Jessie, nginx dejó de funcionar correctamente. Servía sin problemas las páginas estáticas pero cuando trataba de interpretar una página php devolvía una página en blanco sin, aparentemente, ningún error. Ni en ficheros de logs, ni por pantalla, ni nada de nada. Parecía más bien un error de php5-fpm que de nginx o, tal vez, de la forma en que se comunican ambos. Probé la comunicación por puertos TCP en lugar de hacerlo por sockets como lo tenía por defecto y el resultado era el mismo… Así que como me pilló entre semana y con mucho trabajo hice una migración de urgencia a apache y lo dejé pendiente hasta que tuviera un ratito libre.
Hoy ya tocaba y la solución ha sido rápida puesto que el “problema” estaba reportado en la bendita lista de bugs de debian desde hace meses, cuando se detectó durante el testing de la nueva versión. Y pongo “problema” entre comillas porque en realidad se trata de un cambio de estructura a partir de la versión 1.6.2 de nginx (la que acompaña a Jessie) y que viene perfectamente documentado en el fichero index.html que se crea por defecto en el directorio /var/www/html (si, esto también cambia y es la nueva ubicación por defecto para las páginas web).
Existe algún otro cambio pero, para resumir, ahora cuando creas un virtual host que necesita usar php en lugar de usar el bloque de configuración que vimos por aquí hace unas semanas tendrás que usar este:

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $request_filename;
    }

Instalando Oracle 11g R2 en Debian 7 Wheezy

Oracle Preguntadlo por ahí y, posiblemente, cualquier administrador de sistemas coincidirá conmigo en que una instalación de Oracle en Linux es una de las cosas más desagradables e ingratasque puedes querer hacer en estos temas. Máxime si pretendes realizarla en una distribución de Linux no soportada directamente por Oracle (Solaris, Red Hat, Suse y alguna mas…). Pero de vez en cuando toca hacerla, que remedio. En esta entrada vamos a ver de forma guiada y paso a paso una instalación de Oracle 11g R2 (11.2.0.1.0) en una Debian Wheezy (7.7) de 32 bits (haciendo pequeñas anotaciones para que también sirva para una de 64) de forma tan “masticada” que es imposible que te falle nada. ¡Manos a la obra!

Los requisitos hardware iniciales no son demasiado exigentes. Oracle funcionará sin problemas en una máquina con 1,5Gbytes de RAM y 20 Gbytes de disco duro (que son las características de la máquina virtual que voy a usar en este ejemplo). Pero cuidado: la partición de swap debería de ser de aproximadamente 1,5 veces el tamaño de la RAM (algo más de 2Gbytes en este caso), debemos de tener al menos 2Gbytes libres en el directorio /tmp durante el proceso de instalación y los binarios de Oracle ocuparan en su ubicación final algo más de 5 Gbytes, así que si tu disco usa diferentes particiones para estos directorios has de cuidar que el reparto de espacio entre ellos sea el adecuado.

En cuanto al software, partiremos de una Debian recien instalada y sólo con el sistema base aunque, durante el proceso, instalaremos algunos paquetes adicionales y un entorno de ventanas ligero para realizar la instalación desde un entorno gráfico.

Empezaremos por instalar los paquetes de dependencias necesarias que son estos:

apt-get install build-essential sysstat unzip libstdc++5 pdksh numactl expat libaio-dev  unixodbc-dev  lesstif2-dev elfutils libelf-dev

Además, como acabamos de decir instalaremos un entorno de ventanas ligero para realizar la instalación desde el entorno gráfico y un navegador para posteriormente poder acceder a la consola de administración:

apt-get install xfce4 chromium

Vamos ahora a modificar algunos de los parámetros de configuración del kernel editando el fichero /etc/sysctl.conf y añadiendo al final del mismo las siguientes líneas:

kernel.shmmax=536870912
kernel.shmall=2097152
fs.file-max=6815744
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048586
fs.aio-max-nr = 1048576
kernel.sem = 250 32000 100 128

Para que tomen efecto las modificaciones en este fichero sin necesidad de reiniciar ejecutamos ahora lo siguiente:

sysctl -p

El instalador de Oracle también nos pedirá que lo ejecutemos desde un runlevel entre el 3 y el 5 mientras que Debian usar el 2 por defecto. Para evitar esta advertencia editaremos el fichero /etc/inittab y, en una de las primeras líneas, hacemos el cambio para usar, por ejemplo, el 3:

id:3:initdefault:

Para modificarlo también en la sesión actual sin necesidad de reiniciar ejecutamos lo siguiente:

telinit 3

Y ahora una pequeña “trampa”. Para que Oracle no se de cuenta demasiado de que estamos haciendo la instalación en una distribución no soportada crearemos unos enlaces en el sistema de ficheros de forma que se encuentre determinados archivos y librerías donde espearía encontrarselos si la instalación se estuviera realizando, por ejemplo, en una Red Hat:

ln -s /usr/bin/basename /bin/basename
ln -s /usr/bin/awk /bin/awk
ln -s /usr/lib/i386-linux-gnu/libpthread_nonshared.a /usr/lib
ln -s /usr/lib/i386-linux-gnu/libc_nonshared.a /usr/lib
ln -s /lib/i386-linux-gnu/libgcc_s.so.1 /lib
ln -s /usr/lib/i386-linux-gnu/libstdc++.so.6 /usr/lib
NOTA: Si estamos instalando sobre una Debian de 64 bits sustituiremos los últimos cuatro enlaces por los siguientes:

ln -s /usr/lib/x86_64-linux-gnu/libpthread_nonshared.a /usr/lib64/
ln -s /usr/lib/x86_64-linux-gnu/libc_nonshared.a /usr/lib64/
ln -s /lib/x86_64-linux-gnu/libgcc_s.so.1 /lib
ln -s /usr/lib/x86_64-linux-gnu/libstdc++.so.6 /usr/lib64/

Vamos ahora a crear un usuario llamado oracle y un grupo llamado dba. Este será el usuario que usaremos para la instalación y posterior administración de nuestra base de datos. Para hacerlo ejecutamos lo siguiente:

groupadd dba
useradd -d /home/oracle -m -g dba -G dba -s /bin/bash oracle

Para asignarle contraseña a este nuevo usuario:

passwd oracle

Ahora creamos los directorios donde realizaremos nuestra instalación:

mkdir -p /opt/oracle/product/11.2.0.1
mkdir /opt/oraInventory
mkdir /opt/oradata

Y asignamos como propietario y grupo los que acabamos de crear unos instantes antes:

chown oracle:dba -R /opt/oracle /opt/oraInventory /opt/oradata

Alteramos ahora algunas de las limitaciones impuestas a este nuevo usuario que hemos creado editando el fichero /etc/security/limits.conf y añadiendo las siguientes líneas al final del mismo:

oracle soft nproc 2047
oracle hard nproc 16384
oracle soft nofile 1024
oracle hard nofile 65536
oracle soft stack 10240

Y por último, en lo que a este nuevo usuario se refiere, editamos el fichero /home/oracle/.profile y añadimos sl final las siguientes variables de entorno:

export ORACLE_HOSTNAME=localhost
export ORACLE_OWNER=oracle
export ORACLE_BASE=/opt/oracle
export ORACLE_HOME=/opt/oracle/product/11.2.0.1
export ORACLE_UNQNAME=orcl
export ORACLE_SID=orcl
export PATH=$PATH:$ORACLE_HOME/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/i386-linux-gnu:/bin/lib:/lib/i386-linux-gnu/:/usr/lib
NOTA: Si en lugar de estar haciendo la instalación sobre una debian de 32 bits lo estuviéramos haciendo sobre una de 64 tendríamos que modificar la última variable de entorno por la siguiente:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/x86_64-linux-gnu:/bin/lib:/lib/x86_64-linux-gnu/:/usr/lib64

Y ya casi casi tenemos todos los preparativos listos. Ahora copiamos los archivos de instalación de Oracle de su página de Training Eval y los dejamos en el directorio /tmp de la máquina.

IMPORTANTE: ¡Asegúrate de descargarte los archivos adecuados! Recuerda que en este ejemplo estamos usando la versión 11.2.0.1.0 de 32 o de 64 bits.

Descomprimimos los dos archivos que nos hemos bajado sobre el directorio /home del usuario oracle:

unzip /tmp/linux_11gR2_database_1of2.zip -d /home/oracle
unzip /tmp/linux_11gR2_database_2of2.zip -d /home/oracle

Y luego borramos los .zip para que no nos ocupen espacio:

rm /tmp/linux_11gR2_database*.zip

Ahora ya si cambiamos al usuario oracle para realizar la instalación:

su - oracle

Y entramos en el entorno gráfico:

startx

Ya en las xfce y desde un terminal ejecutamos el instalador de Oracle:

/home/oracle/database/runInstaller

Tomaremos casi siempre los valores por defecto de la instalación a menos que te manejes bien con los conceptos de esta base de datos y sepas lo que estás haciendo. Además, muchos de los valores básicos los tomará de las variables de entorno que hemos creado anteriormente en el profile del usuario oracle.
En el tercer pantallazo tendremos que introducir la contraseña del administrador: la del usuario SYS. No la olvides aunque luego, en uno de los pasos finales, tendremos la opción de cambiarla y/o modificarla.

Oracle

Posteriormente en la comprobación de requisitos nos marcará varios fallos relativos a programas que parece no encontrar pero que, sin embargo, hemos instalado previamente. Esto es normal debido a las diferencias de rutas entre Debian y Red Hat. Estos deberían de ser los únicos errores que se nos presentarán si hemos hecho correctamente todo el proceso anterior. Nos aseguramos de ello y, si es así, marcamos el check de Ignorar todo y proseguimos la instalación.

Oracle

A mitad de la instalación nos aparecerá un error como el del pantallazo siguiente. No pulses ningún botón aún y no te pongas nervioso que tiene solución 😉

Oracle

Abrimos un terminal y editamos uno de los scripts que está usando el instalador. Este: /opt/oracle/product/11.2.0.1/sysman/lib/env_emagent.mk . En torno a la línea 2764 nos encontraremos algo así:

NMEFET_STACKLIBS_LINK=$(LDPATHFLAG)$(ORACLE_HOME)/$(LIBDIR)  $(LDPATHFLAG)$(PRODLIBHOME) $(LLIBNMEMSO) $(LLIBCORE) -Wl,-rpath,$(AGENTRPATH):$(JAVA_RTLINK_PATH) $(LIB_JVM_LINK) -Wl,--allow-shlib-undefined

Debemos de añadir el argumento -lnnz11 de forma que quede así:

NMEFET_STACKLIBS_LINK=$(LDPATHFLAG)$(ORACLE_HOME)/$(LIBDIR)  $(LDPATHFLAG)$(PRODLIBHOME) $(LLIBNMEMSO) $(LLIBCORE) -lnnz11 -Wl,-rpath,$(AGENTRPATH):$(JAVA_RTLINK_PATH) $(LIB_JVM_LINK) -Wl,--allow-shlib-undefined

Salvamos el fichero y, ahora así, volvemos a la ventana de advertencia anterior y pulsamos el botón de Reintentar. La instalación debería de proseguir ahora ya sin problemas.

NOTA: Gracias a Gaius por este “truco de magia” así como por otras importantes referencias que me han ayudado a confeccionar esta chuleta.

En unos minutos accederemos a la ventana final del instalador donde se nos mostrará un resumen y se nos permitirá modificar bloquear y desbloquear usuarios por defecto y/o modificar las contraseñas de los mismos:

Oracle
Oracle

Y, ahora ya si por último, el instalador nos pedirá que lancemos un par de scripts adicionales de forma manual como usuario root (recuerda que toda la instalación desde el entorno gráfico la estamos haciendo con el usuario oracle que hemos creado previamente).

Oracle

Abrimos otro terminal distinto al que estamos usando para el instalador y ejecutamos lo que se nos pide:

su
/opt/oraInventory/orainstRoot.sh
/opt/oracle/product/11.2.0.1/root.sh

Y ya hemos terminado. Ahora para acceder a la base de datos puedes usar SQL*Plus desde la línea de comandos o la consola de administración gráfica desde el navegador a través de la URL https://localhost:1158/em y usando la contraseña del usuario SYS (conectando como SYSDBA) que has proporcionado durante la instalación.

Oracle
Oracle

Unas notas para terminar. La instalación no configura a Oracle para que arranque por defecto tras un reinicio del sistema. Es decir, cada vez que hagamos un reboot de la máquina tendremos que volver a levantar los servicios manualmente. Tres son los componentes básicos a considerar: el llamado “listener” de Oracle (el proceso principal que proporciona la conectividad con las bases de datos), la consola de administración y la propia base de datos en si. Para levantar el primero tenemos disponible un script llamado dbstart en el directorio /opt/oracle/product/11.2.0.1/bin. Habiendo hecho logon con el usuario oracle ejecutamos lo siguiente:

dbstart $ORACLE_HOME

Y para detenerlo:

dbshut $ORACLE_HOME

Para arrancar y parar manualmente la consola de administración tenemos que abrir el script de arranque (en el fichero /opt/oracle/product/11.2.0.1/bin/emctl ) y modificar el shebang para indicar que usaremos bash, que es el shell por defecto que hemos elegido para el usuario oracle:

#!/bin/bash -f

Salvamos el fichero y, ahora si, para arrancar la consola usamos este comando:

emctl start dbconsole

Y para detenerla:

emctl stop dbconsole

Para levantar la base de datos podemos usar SQL*Plus como se nos indica aquí o entrar en el entorno gráfico y hacerlo desde la consola de administración. Si entramos en la consola nos advertirá de que la base de datos no está levantada:

Oracle

Pulsamos el botón de Startup (arriba a la derecha) y en la ventana resultante nos autenticamos usando las credenciales del usuario oracle del sistema operativo:

Oracle

Se nos pedirá confirmación de la operación y, si la damos, la base de datos se levantará y estará ya lista para su uso.

Políticas de contraseñas y control de acceso en Debian

seguridad Existe un falso tópico por ahí que viene a decir, de una u otra forma, que Linux es más seguro que Windows. Para nada. Es cierto que, normalmente, el usuario medio de Linux está más comprometido con la seguridad, abundan más los usuarios expertos y menos los usuarios domésticos y que existe una mayor variedad de posibilidades y herramientas para hacer seguros nuestros sistemas. También que al existir un volumen menor de equipos con Linux no es objetivo prioritario de los creadores de virus. Pero “recién salido de la caja” y en manos de un usuario torpe y/o despreocupado, un Linux es, por regla general, tan poco seguro como cualquier Windows. De veras.

Veamoslo, por ejemplo, desde el punto de vista de la política de usuarios y contraseñas, uno de los aspectos que mas se critica en los Windows de escritorio. Una Debian 7.3 (la última en el momento de escribir esto) te permite poner cualquier contraseña para el root y la cuenta inicial que se crean de forma obligatoria durante la instalación. Y cuando digo cualquiera, digo cualquiera y sin ningún tipo de advertencia. ¡Hasta una de un sólo carácter o el maldito 123456 (que hace años que ya ni siquiera en Hotmail está permitida aunque sigue siendo una de las passwords más usadas)! Además, el único tipo de protección ante ataques de diccionario y/o fuerza bruta es un retraso de tres segundos entre cada intento de login fallido. No, no parece un planteamiento muy seguro a priori ¿Verdad? Bueno, por lo menos no nos permite dejar las cuentas sin contraseña. Algo es algo…

NOTA: Si durante la instalación dejamos la password del usuario root en blanco nos lo permitirá pero en ese caso, afortunadamente, lo que hará sera deshabilitar la cuenta de root y conceder privilegios a través de sudo a la cuenta del primer usuario que… igualmente, podremos inicializar con cualquier contraseña sin ningún tipo de advertencia. ¡Ay!

La parte positiva del asunto es que con un poquito de trabajo por nuestra parte este esquema puede mejorar sustancialmente. Para ello, lo primero es conocer como funciona la autenticación de usuarios en Linux. Vamos a ello.

Antes que nada vamos a ubicar algunos de los ficheros importantes en este asunto. En el directorio /etc se encuentran los ficheros passwd y shadow que guardan, respectivamente, las cuentas de usuario y los “hashes” de las contraseñas. Además, repartido entre ellos, existe mucha información relacionada con el proceso de autenticación: si el usuario puede hacer login interactivo o no, el bash que usará, información de caducidad de la cuenta, etc. Veamos una línea típica de cada uno de estos ficheros y hagamos una disección de su contenido.

Empezamos por el fichero passwd. Cada línea se corresponde con un usuario y consta de siete campos en los que el separador es el signo “:”. Por ejemplo así:

josemaria:x:1001:1001:Jose Maria Morales,,,:/home/josemaria:/bin/bash

El significado de cada uno de los campos es este:

1Nombre que el usuario utilizará en el login
2Tradicionalmente aquí se encontraba la hash del password. Ahora, una x simboliza que la hash de la password se encuentra en el fichero shadow. Un * o un ! indican que la cuenta está desactivada. Por el contrario, si eliminamos la x (o cualquier otra cosa) de este campo, el sistema nos dejará entrar sin necesidad de contraseña pero sólo a través de una conexión "in situ" frente a la máquina mientras que las conexiones remotas no se permitiran.
3UID del usuario
4GID del grupo primario del usuario
5Infomación personal del usuario. Los diferentes campos están separados por comas.
6Directorio home del usuario
7Path absoluto al shell por defecto que usará cuando realice una conexión interactiva. Se suele poner /bin/false cuando no queremos permitir una conexión interactiva.

Aquí ya podemos hacer la primera “personalización” relativa a la seguridad. Si queremos que un usuario no pueda hacer una conexión interactiva con el sistema basta con que pongamos un * o un ! en el campo 2 o un shell inexistente en el campo 7 (por convención suele ponerse /bin/false). La diferencia entre usar uno u otro método es que el segundo permitirá que, aún así, esa cuenta de usuario pueda seguir usándose para otro tipo de servicios (correo, por ejemplo) mientras que si usamos el primero la cuenta quedará totalmente inutilizable para ningún servicio.

Vayamos ahora con el fichero shadow. Primero un ejemplo. Como podemos ver, en este caso tenemos 8 campos:

josemaria:$6$F3PRa1Vu$fXK1ZYXex67wi5XdbnTokhWle416I87oAtgs0ynFdhn.c6IBqrvGhmnCUC.Ue2AbLJtn9C9ZH.3pgNfSeneTF0:15675:0:99999:7:::
1Nombre que el usuario utilizará en el login
2Se trata de un campo compuesto que contiene información del algoritmo que usará el sistema para calcular el hash, la salt que aplicaremos a la password antes de calcular este y el hash resultante. Cada uno de estos tres subcampos se separan por el símbolo $. En el ejemplo de aquí arriba el 6 del primer campo indica que usaremos SHA512 (la opción por defecto en las Debian actuales), la salt es F3PRa1Vu y el resto después del último símbolo $ es la hash ya calculada al resultado de concatenar la salt con el password. Un 5 en el primer campo indica que usaremos SHA256, un 4 SHA1, un 3 NT Hash, un 2 blowfish y un 1 MD5. Un * o un ! en este campo también indican que la cuenta está deshabilitada.
3Fecha del último día en que se cambió la password indicada, como es habitual, mediante el número de días transcurridos desde el 1 de Enero de 1970
4Número mínimo de días requeridos entre cambios de contraseñas. Un 0 indica que se puede cambiar tan a menudo como se quiera.
5Número máximo de días para obligar a un cambio de contraseña. Por defecto 99999. O sea, casi 274 años. O sea, nunca.
6Número de días antes de que el password expire en que se mostrará un aviso al usuario indicando que debe de cambiarla. Por defecto 7 días
7Número de días del periodo de gracia después de que el password expire transcurridos los cuales la cuenta será deshabilitada. En blanco por defecto (no habrá periodo de gracia).
8Fecha (indicada también mediante el número de días transcurridos desde el 1 de enero de 1970) en que la cuenta será deshabilitada. En blanco por defecto (la cuenta nunca expira).

La expiración de passwords y de cuentas de los parámetros que hemos visto se puede manejar de dos formas: editando directamente la información del fichero shadow o con el comando chage. Por ejemplo, el siguiente comando fija en 30 días la validez máxima de una contraseña para el usuario josemaria y en 2 el mínimo número de días que deben de transcurrir entre cambios:

chage -M 30 -m 2 josemaria

Otros parámetros interesantes son -d y -E para establecer la fecha del último cambio de contraseña y la de caducidad de la misma respectivamente (en formato YYYY-MM-DD), -I para establecer los días de gracia antes de desactivar la cuenta, o -W para establecer el número de días antes de la fecha de caducidad para emitir una advertencia.

También podemos cambiar todos estos datos de forma interactiva:

comando chage en forma interactiva

O listar los valores establecidos para una cuenta usando el argumento -l:

chage -l josemaria

Pero ¿Dónde se establecen estos valores por defecto para que se tengan en cuenta a la hora de crear nuevos usuarios y no tener que modificarlos uno a uno? En el fichero /etc/login.defs podemos editar los siguientes parámetros que sirven, respectivamente, para ajustar el número máximo y mínimo de días de validez de una password y la antelación a que caduque con que recibiremos una advertencia:

PASS_MAX_DAYS   60
PASS_MIN_DAYS   2
PASS_WARN_AGE   5

En el fichero /etc/default/useradd ajustamos los días de gracia en que las cuentas permarecerán activas después de caducar las contraseñas y la fecha global de expiración de las mismas:

INACTIVE=2
EXPIRE=

Un -1 en el primer campo indica que la cuenta se deshabilitará tan pronto como caduque la contraseña. Si el segundo campo está en blanco indica que la cuenta no tendrá una fecha predeterminada de expiración.

Pero la verdadera potencia en el sistema de identificación de Linux reside en la gran variedad y flexibilidad que tenemos a la hora de usar métodos que refuerzan el sistema clásico de autenticación o nos proporcionan alternativas al mismo mediante módulos adicionales. Estos módulos residen en el directorio /lib/i386-linux-gnu/security/ y se configuran a través de los ficheros que tenemos en /etc/pam.d. En este enlace podemos ver todos los disponibles en una Debian 7 estable, aun los no instalados por defecto. Empecemos por ver dos de los que vienen instalados “de serie”. pam_faildelay y pam_tally nos permiten, a través del fichero /etc/pam.d/login, controlar el retraso entre varios intentos de login fallidos y la configuración de bloqueo de cuentas después de sucesivos intentos erroneos con los siguientes parámetros:

auth optional pam_faildelay.so delay=5000000
auth required pam_tally.so deny=5 unlock_time=7200

En la primera línea el retraso entre logins fallidos se especifica en microsegundos (5000000, o sea, 5 segundos). En la segunda línea decimos que tras cinco intentos de login fallido la cuenta se bloqueará durante 7200 segundos (2 horas). En una instalación limpia y por defecto la primera línea aparece configurada a 3 segundos y la segunda no aparece, es decir, la cuenta no se bloquea nunca.

El control manual de las cuentas bloqueadas o intentos fallidos de login puede llevarse mediante dos utilidades: pam_tally o faillog.

pam_tally y faillog para control de cuentas bloqueadas e intentos fallidos de login

Podemos, además, consultar los datos relativos a una única cuenta de usuario con cualquiera de estos dos comandos:

pam_tally --user josemaria
faillog -u josemaria

Desbloquear manualmente una cuenta o hacer un reset a los intentos fallidos de la misma así:

pam_tally --user josemaria --reset=0
faillog -r -u josemaria 

O modificar el número máximo de intentos fallidos así:

faillog -m 3
NOTA: Los bloqueos tras sucesivos intentos fallidos se pueden controlar también con utilidades externas como denyhost (de la que hablamos aquí hace años) o fail2ban que añaden muchas otras funcionalidades.

El tipo de contraseñas permitidas y alguna otra característica asociada a las mismas se configura en el fichero /etc/pam.d/common-password. La configuración por defecto usa el módulo pam_unix y se define mediante esta línea:

password [success=1 default=ignore] pam_unix.so obscure sha512

El argumento obscure realiza una mínima comprobación de la complejidad de la contraseña: si esta es demasiado simple o una modificación fácilmente reproducible a partir de la anterior, mientras que sha512 define el algoritmo que se usará para guardar el hash en el fichero shadow. Otros argumentos interesantes que podemos añadir son remember, que dicta el número de contraseñas que son memorizadas por el sistema para que el usuario no las repita o minlen que fija la longitud mínima de la contraseña. Por ejemplo, para recordar las 12 contraseñas anteriores y fijar una longitud mínima de 10 caracteres modificaríamos la línea anterior así:

password [success=1 default=ignore] pam_unix.so obscure remember=12 minlen=10 sha512

El módulo pam_cracklib, que no viene instalado por defecto, nos permite una configuración mucho más flexible. Lo instalamos así:

apt-get install libpam-cracklib

Y, tras hacerlo, se nos añadirá automáticamente la siguiente línea en el fichero /etc/pam.d/common-password justo encima de la que define la forma de funcionar del módulo pam_unix:

password requisite pam_cracklib.so retry=3 minlen=8 difok=3

pam_cracklib es mucho más restrictivo que pam_unix a la hora de permitir contraseñas puesto que, además de las comprobaciones de complejidad, contrasta la password elegida por el usuario con las de un diccionario que instala en el directorio /var/cache/cracklib. Además, en su configuración por defecto que acabamos de ver exige una longitud mínima de 8 caracteres de los cuales, al menos, tres no debería de estar presentes en la password anterior (argumento difok). Otros argumentos interesantes son reject_username (rechaza contraseñas que contengan de alguna forma el nombre de usuario escrito normal o invertido) o maxrepeat=n (rechaza contraseñas con más de n caracteres iguales seguidos).

Particularmente flexible es el método que nos permite definir el tipo de caracteres que exigiremos a la contraseña. pam_cracklib considera que existen cuatro grupos de caracteres: letras mayúsculas, letras minúsculas, cifras y signos de puntuación. La forma más sencilla es definir el mínimo número de estos tipos que deberían de estar presentes en cada contraseña con el argumento minclass=n, donde n es un número entre 1 y 4.

Contamos, además, con los argumentos lcredit, ucredit, dcredit y ocredit que representan, respectivamente, a las letras minúsculas, las mayúsculas, los dígitos y los signos de puntuación, los cuatro grupos de caracteres a considerar. Cuando aparecen con valores negativos indican el mínimo número de caracteres de ese grupo con que debería de contar nuestra password. Por ejemplo, minlen= 8 ucredit=-1 lcredit=-1 dcredit=-1 indica que la contraseña debería de tener al menos una mayúscula, una minúscula y un dígito y contar con 8 caractéres mínimos de longitud. Cuando se utilizan con valores positivos, sin embargo, validan nuestra contraseña según un sistema de créditos donde minlen indicaría el número de “puntos” mínimo que validaría una contraseña como correcta. La contraseña sumaría un punto por cada carácter de longitud y los puntos correspondientes a las clases de caracteres que incluya. Pongamos, por ejemplo, que hemos establecido los argumentos minlen= 13 ucredit=1 ocredit=2 dcredit=2. La contraseña tristr4s suma diez puntos (ocho por longitud y dos más por contener un dígito) y no sería valida, mientras que Tristr4s! sumaría 14 (nueve por longitud, una por tener mayúsculas, dos por tener un dígito y otros dos por tener un signo de puntuación) y si sería permitida.

En las páginas del manual de cada uno de estos módulos puedes encontrar algunos otros argumentos interesantes.

IMPORTANTE: La mayor parte de estas restricciones se tendrán en cuenta sólo en el caso de que sea el propio usuario quien realice su cambio de contraseña. Si es el usuario root quien la establece inicialmente o la cambia se le permitirá saltarse a la torera la gran mayoría de estas normas, a veces sin siquiera una advertencia.
ACTUALIZACIÓN: En Security by Default publican esta semana esta entrada con información mucho más técnica sobre los módulos de autenticación PAM donde, además, los analizan como posible punto para comprometer a un sistema.

RAID por software en Debian 7 con mdadm

hard disk Para el que no lo sepa, un RAID en informática no es una carrera de aventuras sino un disco duro lógico creado a partir de la union de dos o más discos duros físicos con objeto (por lo general aunque no siempre) de proporcionar tolerancia a fallos. Las siglas vienen de Redundant Array of Inexpensive Disks y hace referencia a que, en su día, constituían una alternativa para proporcionar un almacenamiento seguro usando discos baratos en lugar de unos mucho más caros (por lo general SCSI). Ahí está la wikipedia para quién quiera aprender un poquito más 😉

El método más seguro de usar esta tecnología es mediante hardware dedicado. Eso que quede claro. Pero cuando no queremos o no podemos gastarnos el dinero que esto requiere tenemos la alternativa de implementarlo mediante software. En Linux tenemos para ello mdadm, una herramienta en línea de comando muy sencilla de usar si entendemos los conceptos básicos de lo que estamos haciendo.

La instalación en una Debian es así de sencilla:

apt-get install mdadm

El script de configuración posterior a la instalación sólo nos planteará dos cuestiones. Leelas atentamente (como siempre… 😉 ). En la primera se nos pregunta si el sistema de ficheros raíz de nuestro Linux estará en un RAID con objeto de iniciarlo antes de la secuencia de arranque. En este ejemplo le diremos que no puesto que sólo usaremos RAID para los discos de datos, así que responderemos con none como se nos indica en el mensaje siguiente:

Instalación de mdadm en Debian Linux
En la segunda pregunta se nos interroga acerca de si queremos que los discos RAID que vamos a crear se inicialicen de forma automática durante cada inicio de la máquina o si preferimos hacerlo nosotros manualmente. Contestaremos que queremos que lo haga de forma automática.

Instalación de mdadm en Debian Linux
Una vez instalado mdadm ya podemos crear nuestro RAID. En el ejemplo que vamos a ver crearemos un RAID5 con tres discos de 500GB. El comando lsblk es muy cómodo para ver que asignación de nombres le ha hecho nuestro sistema a estos dispositivos:

Comprobando la asignación de nombres de dispositivos a nuestros discos duros con lsblk
El comando básico para crear un RAID es este:

mdadm --create dispositivo-md --level=x --raid-devices=z dispositivos-sd

O en formato abreviado:

mdadm --create dispositivo-md -l x -n z dispositivos-sd

Donde x es el nivel de RAID (admite los básicos 0, 1, 4, 5, 6, 10 y alguno más) y z el número de discos que formarán el array. El dispositivo-md será el nombre de dispositivo que recibirá el nuevo disco lógico (y que debería de estar en el directorio /dev y, por convención, llamarse md seguido de un número, por ejemplo /dev/md0) y los dispositivos-sd serían los discos físicos que forman el array separados por espacios (por ejemplo /dev/sdb /dev/sdc). Podemos añadir también la opción --verbose para obtener información más detallada del proceso de creación y los posibles fallos. Veamos un par de ejemplos:

Para crear un RAID0 con los tres discos indicados:

mdadm --create --verbose /dev/md0 --level=0 --raid-devices=3 /dev/sda /dev/sdb /dev/sdc

Para crear un mirror (RAID1) con los discos indicados:

mdadm --create /dev/md0 -l 1 -n 2 /dev/sdb /dev/sdc

La creación admite, aparte de estas, otras opciones avanzadas que puedes consultar en el manual que se ha instalado con él (man mdadm). Y vamos ya a seguir con nuestro ejemplo. Para crear el RAID5 que necesitamos ejecutamos lo siguiente:

mdadm --create --verbose /dev/md0 --level=5 -n 3 /dev/sdb /dev/sdc /dev/sdd

Si todo ha salido bien se nos mostrarán algunos mensajes informativos y el comando finalizará indicando que el disco md0 ha sido inicializado y arrancado. Podemos comprobar el estado de nuevo con lsblk o con more /proc/mdstat
Comprobando el estado de un RAID5 recién creado con mdadm

Para poder utilizar nuestro disco debemos aún formatearlo y montarlo en nuestro sistema de ficheros. Vamos a formatearlo como ext4 y a montarlo en un directorio que se llame datos dentro del subdirectorio /mnt:

mke2fs -t ext4 /dev/md0
mkdir /mnt/datos
mount /dev/md0 /mnt/datos

Si usamos ahora, por ejemplo, el comando df (df -k /mnt/datos) para ver el espacio de la partición y el porcentaje de uso veremos que, efectivamente, disponemos de cerca de 1TB correspondiente al tamaño del RAID5 con tres discos de 500GB que hemos montado.

Nos falta aún algo más. Durante la instalación le hemos dicho a mdadm que inicie de forma automática todos los arrays, pero eso no significa que los monte en el sistema de ficheros. Si queremos que lo haga automáticamente en cada arranque y en el mismo directorio donde lo acabamos de hacer de forma manual, tendremos que añadir una línea como la siguiente al fichero /etc/fstab:

/dev/md0  /mnt/datos  ext4  defaults  0  1

Vamos a echarle ahora un vistazo a diversos comandos de gestión y monitorización. Si queremos detener el volumen usamos el argumento --stop. No olvides desmontarlo antes para evitar que haya pérdida de datos:

umount /dev/md0
mdadm --stop /dev/md0

Luego, para volver a arrancarlo de forma manual:

mdadm --assemble /dev/md0 /dev/sdb /dev/sdc /dev/sdd

Y si habíamos incluido la línea que indicamos antes en el fichero fstab para volver a montar el disco en nuestro sistema de ficheros basta con hacer esto:

mount /dev/m0 /mnt/datos

Para ver información de todos los arrays que tenemos en funcionamiento en la máquina usamos el argumento --detail:

mdadm --detail --verbose --scan

Información de los RAID en una máquina con mdadm

Sólo tenemos uno, claro. Para ver información en detalle del mismo:

mdadm --detail --verbose /dev/md0

Información en detalle de un RAID con mdadm

O también podemos usar el argumento --examine para ver información y el estado de cualquier a de los discos que forman nuestro array:
Información en detalle de uno de los discos de un RAID con mdadm

Vamos a simular ahora la rotura de uno de los discos. Para ello apagamos la máquina bruscamente y desconectamos uno de los tres discos del RAID. Podemos hacer fácilmente esta prueba tanto en una máquina real (¡que no esté en producción!) como en una virtual. Tras arrancar de nuevo nuestro RAID habrá perdido la tolerancia a fallos. No obstante, si hemos creado o copiado datos en el directorio /mnt/datos veremos que estos siguen siendo perfectamente accesibles.

OJO: Si el RAID no estaba aún totalmente inicializado (hemos usado discos muy grandes y no ha pasado suficiente tiempo desde su creación o desde la última vez que se recuperó de un fallo) el volumen no arrancará correctamente. Es por tanto muy importante no comenzar a usarlo hasta que no se ha inicializado completamente y extremar las precauciones después del fallo de algún disco hasta que volvemos a recuperar la tolerancia a fallos. Si miramos el pantallazo de aquí arriba en el que aparece la salida de ejecutar more /proc/mdstat vemos que allí aparece una barra de progreso donde se indica el estado de creación o reconstrucción del RAID. Mientras que esa barra no llegue al 100% y desaparezca mejor que no tengas ningún problema 😉

Para recuperar la tolerancia a fallos debemos de añadir un disco nuevo. Lo hacemos y una vez arrancada de nuevo la máquina ejecutamos lo siguiente para añadir el disco /dev/sdc a nuestro RAID en sustitución del que hemos simulado que se ha roto:

mdadm /dev/md0 --add /dev/sdc

El RAID se reconstruirá sólo de forma automática pero dependiendo del tamaño y del volumen de datos podrá tardar más o menos tiempo. Observa de vez en cuando la salida de more /proc/mdstat para estar al tanto.

OJO: Después de perder un disco los nombres de los dispositivos pueden haber ??bailado?. Es muy importante que comprobemos antes (con lsblk, por ejemplo) cuales son los que siguen formando parte del array y cual el nuevo que queremos añadir.

Si lo que queremos es añadir al RAID un nuevo disco para que sea usado como hot spare basta con sumarlo a un RAID ya creado y funcional con el mismo comando que usamos antes para añadir un disco a un RAID estropeado:

mdadm /dev/md0 --add /dev/sde

Si lo que queremos es añadir el disco para agrandar el tamaño del RAID y no para que sea usado como hot spare tendríamos que usar los siguientes comandos:

mdadm /dev/md0 --add /dev/sde
mdadm --grow /dev/md0 ??raid-devices=4

En el fichero /proc/mdstat podemos ver el proceso como siempre:
Haciendo crecer nuestro RAID añadiendo un nuevo disco

Lo que no nos va a resolvernos mdadm es hacer que la partición que habíamos creado en el disco y sobre la que estábamos trabajando crezca. Eso es tarea nuestra:

umount /dev/md0
e2fsck -f /dev/md0
resize2fs /dev/md0
mount /dev/md0 /mnt/datos

Y el resultado:
Extendiendo la partición de un RAID al que hemos añadido un nuevo disco

NOTA: Como se puede observar, durante este último proceso de crecimiento del RAID hemos trabajado con cuatro discos (tres originalmente) de 1GB cada uno en lugar de los de 500GB que hemos usado en el resto del tutorial. Quería que se apreciara el cambio de tamaño del volumen y la resincronización de discos tan grandes habría supuesto tener que esperar muchas horas para poder visualizar el proceso completo.

Si lo que queremos es eliminar uno de los discos del RAID (para reemplazarlo por otro, por ejemplo) tenemos antes que marcarlo como fail. Luego lo eliminamos:

mdadm /dev/md0 --fail /dev/sdd
mdadm /dev/md0 --remove /dev/sdd

Y si quisiéramos eliminar el RAID usamos este comando:

mdadm --remove /dev/md0

mdadm tiene también un argumento llamado --monitor que le permite generar alertas cuando ocurre alguna incidencia en el RAID. Por defecto en una Debian el monitor se arranca como un daemon que graba las incidencias en el fichero de logs de la máquina (/var/log/syslog) de esta forma:

mdadm --monitor --pid-file /run/mdadm/monitor.pid --daemonise --scan --syslog

Si, además, quisiéramos que nos enviara dichas incidencias a nuestra cuenta de correo deberíamos de añadir la opción --mail:

mdadm --monitor --pid-file /run/mdadm/monitor.pid --daemonise --scan --syslog --mail josemaria@uponday.net

Greylisting en Postfix y Debian 7

correoNadie se acuerda de Santa Bárbara hasta que truena, que dice el refrán. Yo tenía pendiente configurar un sistema de Greylisting (listas grises) en mi servidor de correo pero no lo he visto como urgente e inmediato hasta el aumento inusitado de actividad de los bots de spam de los últimos días.

El Greylisting es, hoy por hoy, uno de los métodos más efectivos a la hora de controlar el spam y su funcionamiento es sencillo y fácil de entender. Cuando un servidor de correo recibe un mensaje anota en una lista tres datos que lo identifican (la IP desde donde viene, el correo del remitente y el del receptor) y a continuación lo rechaza indicando al emisor que lo intente de nuevo más tarde. Esto se hace con un código 45x:

-> MAIL FROM: <sender@somedomain.com>
<- 250 2.1.0 Sender ok
-> RCPT TO: <recipient@otherdomain.com>
<- 451 4.7.1 Please try again later

Si el mensaje ha sido enviado por un servidor SMTP legítimo reconocerá el mensaje de rechazo y en un tiempo predefinido (típicamente de 300 segundos) reenviará de nuevo el correo que, en este caso, será aceptado por el servidor del destinatario. Un bot preparado para enviar spam no realizará el segundo envío. De esta forma, si el correo no es spam llegará al destinatario con 5 minutos de retraso. Salvo este detalle el emisor no se enterará de nada (todo el trabajo se hace entre los servidores de correo sin que los clientes intervengan). Si el receptor abre la cabecera del mensaje recibido verá una línea parecida a esta:

X-Greylist: delayed 300 seconds by postgrey-1.34 at invernalia; Thu, 19 Sep 2013 16:30:33 CEST

El sistema de control del spam mediante Greylisting fue originalmente ideado por Evan Harris en este whitepaper de 2003. El señor Harris mantiene, además, una lista de implementaciones de su método para diversos servidores de correo. Si quieres más información conceptual sobre esta técnica, esta página y la entrada correspondiente de la wikipedia también tienen información interesante.

Si ya tienes una Debian con un servidor de correo postfix funcionando la implementación en perl del Greylisting es muy, muy fácil de poner en marcha. Basta con instalar el paquete postgrey y añadir check_policy_service inet:127.0.0.1:10023 en la lista de restricciones del fichero main.cf de configuración de postfix en el directorio /etc/postfix:

smtpd_recipient_restrictions = reject_unknown_sender_domain, reject_unknown_recipient_domain, reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_policy_service inet:127.0.0.1:10023

Por supuesto, una vez hechas ambas cosas debemos de reiniciar el servicio postfix. La instalación nos ha creado un nuevo servicio llamado postgrey que arranca como daemon y escucha en el puerto 10023 y que responde a los argumentos habituales: start, stop, restart, reload, force-reload y status. En el directorio /etc/postgrey tenemos dos ficheros denominados whitelist_clients y whitelist_recipients donde, respectivamente, se pueden especificar las direcciones de ciertos servidores smtp o direcciones de correo que no se someteran al procedimiento de rechazo temporal de los mensajes y que se aceptaran al primer intento. Tenemos, además, un fichero donde se encuentra la configuración principal del servicio llamado /etc/default/postgrey que veremos más adelante.

Si observamos ahora el log de nuestro postfix (/var/log/mail.log) podemos estudiar el funcionamiento y si este es correcto. Cuando recibimos cualquier correo (salvo uno ya identificado como válido en las whitelist) será inmediatamente registrado y rechazado:

Al cabo de cinco minutos si el correo es legítimo el servidor remitente volverá a intentarlo y ahora el correo si será aceptado:

Puede que el servidor emisor se impaciente y antes de que transcurran esos cinco minutos vuelva a intentarlo. En ese caso el correo volverá a ser rechazado:

Como puedes observar en los mensajes del log, aparte de la razón del rechazo el servidor enviará una dirección web personalizada donde se informa detalladamente de lo que está ocurriendo:

mensaje de información de postgrey en castellano

Postgrey crea, además, una base de datos en el directorio /var/lib/postgrey donde guarda información acerca de los mensajes recibidos. Después de aceptar cinco mensajes de un servidor, este será automáticamente incluido en una whitelist de tal forma que, a partir de este momento, ya no se le volverá a exigir el trámite de los reintentos. Podemos consultar en cualquier momento los servidores de esta lista ejecutando el siguiente script:

perl /usr/share/doc/postgrey/postgrey_clients_dump

Y una ejecución de ejemplo:

Servidores incluidos en la whitelist de greylist

Tenemos aún pendiente ver el fichero de configuración principal: /etc/default/postgrey. En el podemos modificar, por ejemplo, el texto que aparecerá en el mensaje de rechazo:

POSTGREY_TEXT="Si tu sevidor funciona como debiera debería de intentar enviarme de nuevo el mensaje en 5 minutillos de nada"

También podemos enviar al demonio cualquiera de los argumentos que tenemos disponibles para modificar su funcionamiento (ver man postgrey) mediante el parámetro POSTGREY_OPTS. Por ejemplo, en la siguiente línea se dice al demonio que escuche en el puerto 60000, subimos el retraso para aceptar el mensaje a 600 segundos y le indicamos que incluya las direcciones de los clientes en la whitelist después de aceptarles 3 envíos:

POSTGREY_OPTS="--inet=60000 --delay=600 --auto-whitelist-clients=3"

Para terminar, si quieres comprobar la configuración de tu servidor de correo electrónico para ver si es vulnerable de alguna forma y puede ser usado como un Open Relay, si el correo saliente que envía puede verse bloqueado de alguna forma, etc. existen muchas herramientas en línea pero las más cómodas y completas, a mi juicio, son las de mxtoolbox y el test de allaboutspam.

ACTUALIZACIÓN: Los servidores de Microsoft (outlook, hotmail…) dan problemas con este sistema desde hace un tiempo. Aquí tienes como resolverlos.

Analizando el arranque de tu Linux con bootchart

herramientas ¿Qué es lo que hace tu Linux durante el arranque?¿Hay alguna forma de ver exactamente que se ejecuta, cuales son los procesos dependientes que genera y cuanto tiempo se invierte en cada uno de ellos de forma que podamos, si es necesario, saber donde tenemos que tocar para conseguir un arranque más rápido?

Bootchart es una herramienta que obtiene y procesa fácilmente esta información y genera como resultado un gráfico fácilmente interpretable. Como muestra, aquí tenéis la gráfica resultado en un servidor VPS con Debian 7 (ya sabes, pulsa sobre la gráfica para verla con mejor resolución):

Gráfica de bootchart 0.9 en un servidor VPS con Debian 7

La instalación básica en una Debian estable requiere dos paquetes (y sus dependencias): bootchart y pybootchartgui. El primero es el que recopila los datos y el segundo el que genera el gráfico a partir de ellos. bootchard se instalará por defecto en el directorio /sbin y su archivo de configuración se llama bootchard.conf y se encuentra en el directorio /etc. pybootchartgui se encuentra en el directorio /usr/bin/. Aunque tenemos muchas opciones interesantes para explorar, vamos a limitarnos a ver el funcionamiento tal y como queda recién instalado y sin tocar nada.

Una vez instalados ambos, tenemos que hacer que el kernel de nuestro Linux ejecute el proceso que realiza la recogida de datos lo antes posible y esto lo hacemos introduciendo dicha llamada directamente en GRUB. Si estamos en un equipo desde el que tenemos acceso directo a teclado y monitor lo más fácil es introducir a mano la opción necesaria en el momento del arranque. Para ello, una vez que nos aparece el menú de GRUB pulsamos la letra “e” (de editar) e introducimos la opción init=/sbin/bootchartd. De esta forma el proceso sólo se llamará en este arranque puesto que la opción no queda salvada:

Editando la entrada de Grub para invocar a bootchar

Si no tenemos acceso al teclado de la máquina en el momento del arranque (en un Hosting VPS, por ejemplo) el método pasa por introducir esta opción en los archivos de configuración de GRUB. El método es diferente según que usemos GRUB o GRUB2. En GRUB basta con editar el archivo /boot/grub/menu.lst, buscar el bloque correspondiente al kernel con el que qeremos realizar el arranque e introducir la misma opción que hemos visto antes. Por ejemplo, así:

title           Debian GNU/Linux, kernel 3.2.0-4-amd64
root            (hd0,0)
kernel          /boot/vmlinuz-3.2.0-4-amd64 root=/dev/vda1 ro quiet no-kvmclock init=/sbin/bootchartd
initrd          /boot/initrd.img-3.2.0-4-amd64

En GRUB2 tenemos que editar el fichero /etc/default/grub, buscar la línea etiquetada como GRUB_CMDLINE_LINUX_DEFAULT e incluir al final de lo que allí aparezca la opción de carga de bootchartd. Así, por ejemplo:

GRUB_CMDLINE_LINUX_DEFAULT="resume=/dev/disk/by-uuid/35a07870-ac1a-489f-a19b-629
6dca46903 init=/sbin/bootchartd"

En este segundo caso, una vez editado el fichero tendremos que ejecutar el programa update-grub para que los cambios tomen efecto.

Un cuarto método, disponible si estamos usando un equipo de escritorio con un gestor de ventanas instalado, es usar uno de los muchos programas existentes para configurar grub de forma gráfica. Por ejemplo, grub-customizer:

Configurando el arranque de bootchartd con grub-customizer

Sea cual sea el método que hayamos usado, en el próximo arranque se ejecutará bootchartd, pero no olvides que, salvo en el primer caso, cuando ya no quieras usarlo tendrás que deshacer los cambios efectuados.

Bien. Tras reiniciar la máquina se invocará al proceso llamado bootchartd que recogerá la información necesaria y la guardará en un archivo llamado bootchart.tgz en el directorio /var/log. Para crear el gráfico basta con invocar a pybootchartgui:

Generando el gráfico de bootchart con pybootchartgui

Nota que se toma por defecto la ubicación y nombre del archivo original y que, por tratarse este de un nombre genérico, cada vez que reiniciemos y/o generemos un nuevo gráfico machararemos los datos del anterior a menos que los renombremos manualmente o le echemos un vistazo a la forma de modificarlos mediante los parámetros en línea y/o opciones de configuración adecuadas. Y listo. A continuación tenéis otro ejemplo correspondiente a un servidor más modesto que el anterior montado sobre VirtualBox:

Gráfica de bootchart 0.9 en una máquina de virtualbox con Debian 7

En la paquetería de Manjaro Linux (e, imagino, que ocurre igual con Arch) se usa otro programa similar también llamado bootchart pero que, en realidad, integra en un sólo servicio la recolección de datos y la generación del gráfico final. El gráfico resultante presenta, además, algunos aspectos diferenciadores. Podéis ver una muestra en la siguiente imagen que corresponde con el arranque de un PC de escritorio:

Gráfica de bootchart 1,2 en un PC de escritorio con Manjaro Linux

Para usarlo basta instalar el paquete llamado bootchart. El programa que tendremos que invocar se llamará igualmente bootchartd pero en este caso reside en el directorio /usr/bin. Podemos usar cualquiera de los métodos anteriormente vistos para invocarlo pero el parámetro a incluir en las opciones de carga del kernel será init=/usr/bin/bootchard. El archivo de configuración también es sensiblemente diferente y está en el directorio /etc/systemd. Cuando reiniciamos la máquina, el archivo que bootchart genera es ya directamente un gráfico en formato svg. El directorio destino del mismo es, igualmente, /var/log pero en este caso el nombre incluye una marca de tiempo (por ejemplo bootchart-20130916-0800.svg) de forma que si realizamos sucesivos reinicios tendremos disponible una colección de gráficos para su posterior estudio sin necesidad de ninguna intervención manual.

Existe aún, al menos, otro tercer sistema similar a estos denominado bootchart2 y que, por el momento, no he tenido ocasión de probar. Ahí queda el enlace por si alguien se anima…

NOTA: Desde hace ya unos meses estoy usando Manjaro Linux (con Openbox como window manager) como distribución de escritorio, tanto en mi ordenador de sobremesa como en mi portatil. Manjaro es una distribución rolling release, muy, muy ligera basada en Arch Linux que me está gustanado bastante, así que previsiblemente hablaremos bastante de ellas en lo sucesivo.

Instalación y primeros pasos con ntop 5 en Debian 6

ntop es la herramienta más popular y completa para monitorizar el tráfico de una red cuando nos interesa, no sólo conocer la magnitud del mismo sino su procedencia y características. Colocado en un punto estratégico de nuestra red nos sirve para detectar cualquier tipo de anomalía en la misma. Si lo instalamos en un servidor nos sirve para auditar el tipo de tráfico que este emite y recibe de forma gráfica y muy didáctica.

Como ocurre en algunas ocasiones la versión en la paquetería de debian (4.0.33 en la estable y 4.99.3 en testing y unstable) va bastante por detrás de la del producto (5.0.1) así que si te apetece jugar con lo último lo mejor es bajarte los fuentes y compilarlos en tu máquina. Pero ya sabes que, en este caso, tendrás que preocuparte de posibles actualizaciones de forma manual. ntop, en particular, no parece tener ningún aviso automático de la aparición de nuevas versiones. Vamos a ello.

Antes que nada, instalamos los paquetes necesarios para realizar la instalación, las dependencias y alguna otra cosa necesaria:

apt-get install build-essential libtool automake autoconf libpcap-dev libgdbm-dev rrdtool librrd-dev libssl-dev python-dev libgeoip-dev graphviz subversion python-pip

A continuación nos descargamos de aquí la última versión estable de ntop, la copiamos en, por ejemplo, el directorio /tmp de nuestra máquina y la descomprimimimos:

wget -c http://sourceforge.net/projects/ntop/files/ntop/Stable/ntop-5.0.1.tar.gz
tar xvfz ntop-5.0.1.tar.gz

Ahora entramos al directorio donde se han descomprimido los fuentes (ntop-5.0.1 en este caso) y generamos los binarios.

cd ntop-5.0.1/
./autogen.sh
make
make install
ldconfig

Y listo. Sólo nos quedan unos cuantos retoques. Los datos que ntop capture una vez esté en funcionamiento se guardarán en /usr/local/var/ntop. El daemon de ntop se ejecuta con el usuario nobody, así que debemos de hacerlo propietario de dicho directorio para que pueda escribir libremente en él:

chown -R nobody /usr/local/var/ntop

El binario de ntop ya está listo para ejecutarse y se encuentra en el directorio /usr/local/bin. Si escribes ntop -help tendrás una detallada lista de posibles opciones. Las mías son estas:

/usr/local/bin/ntop -i eth0 -w 3001 -L -d

De esta forma ntop monitorizará todo el tráfico enviado y recibido por el interfaz de red eth0 de nuestra máquina, el interface web de ntop escuchará peticiones en el puerto 3001 (por defecto lo haría en el 3000), guardará los mensajes de log en el syslog de la máquina (/var/log/syslog) y se ejecutará como daemon o servicio en segundo plano.

En la primera ejecución nos pedirá que introduzcamos la contraseña para el usuario admin necesaria para entrar a ciertas páginas restringidas del programa. Muy pocas, la verdad, pero luego veremos como solucionar esto.

ACTUALIZACI?N: Las últimas compilaciones llevan por defecto la contraseña admin para el usuario admin

Para acceder a ntop ya sólo tenemos que ir a nuestro navegador y escribir lo siguiente sustituyendo ip-de-la-maquina por la dirección o nombre correcto donde hemos hecho la instalación y cambiando el puerto por el adecuado si lo hemos modificado en la orden de inicio anterior:

http://ip-de-la-maquina:3001

Pantalla principal de ntop (Traffic Summary)

Para proteger el acceso a cualquier página de ntop (imprescindible sobre todo si es visible desde Internet) debemos de entrar en el menú superior (Admin -> Configure -> Protect URLs) y añadir una regla con un asterisco ‘*’ al limitado grupo de usuarios que deseemos (o al usuario admin si es una instalación de uso particular).
Protegiendo el acceso a ntop

Ahora ya sólo nos quedan unos pequeños ajustes para disponer de algunos gráficos y diagramas adicionales que, por defecto, no vienen configurados. El plugin Round-Robin Database debería de estar activado para disponer de los gráficos de Network Load generales o por protocolo.
Gráficos de carga por protocolo en ntop con rrd activado

Para ello, además de activar el plugin (Plugins -> Round-Robin Database -> Activate), deberíamos de comprobar que en la pantalla de Preferencias (Admin -> Configure -> Preferences) la cadena rrd.rrdPath apunta a un directorio donde el usuario nobody tenga permisos de escritura (típicamente /usr/local/var/ntop/rrd), que en la configuración del plugin (Plugins -> Round-Robin Database -> Configure) las dos cadenas del bloque RRD Files Path apuntan al mismo directorio y que en el bloque Data to Dump de esta misma pantalla tenemos seleccionada, al menos, la opción de Interfaces. Si seleccionamos todas las opciones tendremos muchos más datos de captura pero a costa de cargar más la ejecución y el espacio ocupado por las capturas. Mucho cuidado con el espacio en disco, que podemos necesitar fácilmente 2 Gigas por día en un servidor con un tráfico corrientito.
Configurando rrd en ntop

Para ver los mapas por regiones tenemos que instalar las plantillas Mako para python. Como al principio de todo hemos instalado el paquete python-pip nos basta con salir a línea de comandos y ejecutar lo siguiente:

pip install Mako

Graficos geográficos con Mako y ntop

Por último, aunque hemos instalado graphviz y Dot es uno de sus elementos integrantes, nos hace falta añadir un path en las Preferencias (Admin -> Configure -> Preferences) para disponer de los Mapas de Tráfico de Red Locales. Entramos en ellas y, al final de la tabla, añadimos la cadena dot.path con el valor /usr/bin/dot. Pulsamos Add, confirmamos y listo.
Gráficos de tráfico de red local en ntop

ntop tiene muchas otras gráficas y páginas de información útil e interesante además de estas que he mostrado y cuyo único motivo para aparecer aquí es que necesitan de algún retoque extra en la configuración para poder usarlas, así que lo mejor es que las explores una a una. La documentación para interpretarlas es escasa, todo hay que decirlo, pero últimamente se están poniendo las pilas en este sentido y han prometido, por fin, un manual de usuario en breve.

Y ya sólo nos queda un pequeño detalle para concluir. Si quieres que ntop se ejecute de forma automática como servicio cada vez que hagas un reinicio de la máquina donde la tienes instalada sólo tienes que crear un fichero .sh (por ejemplo ntop.sh) con la línea de ejecución que has usado antes para ponerlo en marcha, crear un enlace al mismo en el directorio init.d y ejecutar lo siguiente:

ln -s /opt/Scripts/ntop.sh /etc/init.d/ntop
update-rc.d ntop defaults 99

Instalando memcached en Debian y habilitando su uso con WordPress

herramientas memcached es uno de los sistemas de caché para servidores web más usado. Usa una zona de la memoria RAM del servidor web de tamaño configurable como caché y funciona bien tanto en sitios pequeños y discretos como en grandes sistemas con múltiples servidores. Facebook, Twitter o Youtube, por ejemplo, usan este sistema de cacheado. El 85% de los 20 sitios con más tráfico de Internet lo usan, en realidad. Nada mejor, pues, para estrenar una pequeña sección acerca de sistemas y extensiones de cacheado para apache ¿no?

Partimos para la instalación de una Debian en la que ya tenemos un servidor web apache y la versión 5 de php (paquetes apache2 y php5). Para instalar memcached en una Debian he tenido que recurrir a usar “paquetería” de wheezy (testing) porque parece que hay algún problema de dependencias en la versión estable (squeeze) y la librería de extensión para trabajar con PHP no compilaba correctamente. Así que manos a la obra. El primer paso es instalar el servidor de memcached:

apt-get install memcached

El servicio se instala, como es habitual, en el directorio /etc/init.d y responde a los argumentos start, stop, restart, force-reload y status. En el directorio /usr/share/memcached/scripts existe un script llamado start-memcached que es el encargado de realizar el inicio automático y que toma la configuración del archivo memcached.conf en el directorio /etc. Dentro de este fichero de configuración una de las opciones más interesantes es la que dice a memcached cuanta RAM va a usar como caché. Por defecto son 64M, pero en sistemas con muy poca RAM tal vez nos convenga bajarlo. Mi VPS tiene sólo 512M de RAM y yo he bajado esos 64M a la mitad. Para ello basta con cambiar la línea -m 64 por -m 32 y reiniciar el servicio.

Otra de las opciones interesantes en ese archivo de configuración es la posibilidad de habilitar un archivo de logs que, por defecto, viene deshabilitado. Para ello basta con quitar el comentario a una de las dos opciones que aparecen el el fichero según el nivel de detalle que queramos: -v o -vv. El log se grabará en el fichero /var/log/memcached.log. Esto también es configurable modificando la línea que aparece en el mismo fichero. Y no olvides que para que la opción tome efecto haz de reiniciar de nuevo el servicio de memcached.

El segundo paso sería instalar la extensión de memcached para PHP. Para ello tenemos que instalar los siguientes paquetes:

apt-get install php-pear php5-dev php5-memcached libmemcached10 libmemcached-dev libmemcachedutil2 libhashkit2 libhashkit-dev

Y, a continuación, ejecutar lo siguiente:

pecl install memcached

Si todo sale bien, al final del proceso se nos mostrará un mensaje similar a este:
Instalación del módulo PHP de memcached

La librería debería de haberse creado en el directorio de extensiones de php que se indica al final del proceso y que puedes ver en la imagen anterior (/usr/lib/php5/20100525+lfs) y ya sólo nos resta hacerle caso al mensaje final y añadir la línea extension=memcached.so al final de nuestro fichero php.ini que debería de estar en el directorio /etc/php5/apache2. Reiniciamos apache y, si ejecutamos la función phpinfo veremos una nueva sección:
phpinfo con información del módulo memcached

Para ver información acerca de como está funcionando nuestra cache tenemos un par de opciones más atractivas que inspeccionar el fichero de log que hemos mencionado antes. Una de ellas es usar el script memcached-tools que encontraremos en el directorio /usr/share/memcached/scripts/.

/usr/share/memcached/scripts/memcached-tool 127.0.0.1:11211

El comando anterior muestra información sobre el estado del servicio memcached que hemos instalado en nuestra máquina. Añadiendo al final el argumento stats nos mostrará estadísticas de uso y con el argumento dump realizará un volcado del contenido de la caché por pantalla.

La segunda opción que tenemos es bajarnos de aquí un script hecho en perl y llamado memcache-top. Tienes distintos argumentos para modificar la salida que puedes consultar en la web desde la que te has bajado el script. En la imagen siguiente se muestra con las opciones --cumulative y --commands
ejecución de memcached-top

Y ya sólo nos queda habilitar el uso de memcached desde wordpress. Para ello usaremos Memcached Object Cache que, aunque aparece como cualquier otro en el repositorio de plugins de wordpress, en realidad precisa de una sencilla instalación manual para que funcione. Bajamos el archivo, lo descomprimimos y copiamos el archivo object-cache.php en el directorio wp-content de nuestra instancia de wordpress.