# rm-rf.es | Administración de sistemas

Bitácora personal de un SysAdmin Gnu/Linux, Windows, BSD...

Seguridad Unix con TCP Wrappers

Seguridad Unix TCP WrappersEl otro día hablábamos sobre securizar un sistema Linux con iptables y en otro artículo encontrábamos un firewall basado en FreeBSD llamado pfSense. Hoy vamos a ver cómo securizar un sistema Unix (Linux, BSD…) a través de TCP Wrappers,  un buen complemento de iptables. La wikipedia lo define como:

TCP Wrapper (“Envoltorio de TCP”) es un sistema de red ACL que trabaja en terminales y que se usa para filtrar el acceso de red a servicios de protocolos de Internet que corren en sistemas operativos (tipo UNIX), como Linux o BSD. Permite que las direcciones IP, los nombres de terminales y/o respuestas de consultas ident de las terminales o subredes sean usadas como tokens sobre los cuales filtrar para propósitos de control de acceso.

Bien, partimos de la base de que tenemos dos ficheros configurables, /etc/hosts.deny y /etc/hosts.allow. En ellos podemos especificar que IPs, hostnames o redes pueden acceder a determinados servicios del sistema. TCP Wrappers suele venir instalado por defecto en la mayoría de sistemas operativos Unix.

La sintaxis básica de estos ficheros es la siguiente:

daemon : dirección : acción
ó
daemon : dirección

Daemon es el demonio/servicio a filtrar, dirección es la dirección, host o subred y acción si denegamos o aceptamos el acceso. Para saber si un servicio puede ser configurado para filtrado vía TCP Wrappers hay que saber si su binario está enlazado con la biblioteca libwrap.a. Para ello:

# ldd /usr/sbin/sshd | grep libwrap.so
	libwrap.so.0 => /lib/libwrap.so.0 (0x001ce000)

Si la salida es NULL el demonio no está compilado con TCP Wrappers y no funcionará. Si devuelve algo como lo anterior sí que lo está. Vamos a ver entonces unos cuantos ejemplos:

Permitir acceso ssh únicamente a unas IPs

/etc/hosts.allow Permitimos acceso a las IPs 192.168.0.111, 192.168.0.112, 192.168.0.113.

sshd: 192.168.0.111 192.168.0.112 192.168.0.113

/etc/hosts.deny Denegamos al resto.

sshd: ALL

Bloquear todo excepto lo declarado en /etc/hosts.allow

/etc/hosts.allow

sshd: 192.168.0.111 192.168.0.112 192.168.0.113

/etc/hosts.deny Denegamos acceso al resto de servicios excepto SSH a las Ips indicadas. La máquina quedará blindada excepto el acceso SSH a las Ips permitidas:

ALL: ALL

Permitir también el uso de sendmail a una subred y unos hosts concretos

/etc/hosts.allow Permitimos acceso a las IPs 192.168.0.111, 192.168.0.112, 192.168.0.113.

sshd: 192.168.0.111 192.168.0.112 192.168.0.113
sendmail: 10.0.0.0/24 test.com prueba.com

/etc/hosts.deny

ALL: ALL

Permitir todo y bloquear el acceso total a una única IP

/etc/hosts.allow

ALL: ALL

/etc/hosts.deny

ALL: 192.168.0.115

Filtrar y ejecutar un comando tras un intento de acceso

/etc/hosts.allow

ALL: ALL

/etc/hosts.deny

ALL: 192,168.0.115 \
   : spawn (/bin/echo %a desde %h intento acceder a %d >> \
    /var/log/connections.log) \
   : deny

Aquí ya depende todo si queremos aplicar una política restrictiva desde el principio, bloquear todo y a partir de ahí comenzar a abrir servicios a determinadas Ips, rangos o hosts o si por el contrario queremos dejar todo abierto y cerrar servicios a determinadas Ips,etc.

Si os resulta interesante, disponéis de más información en el handbook de freebsd o en Linux about.com. Esta ha sido una mera introducción a TCP Wrappers

Repositorio CentOS-5.6 Continuous Release ( CR ) disponible

CentOSCentOS ha publicado un nuevo repositorio a través de mirror.centos.org. CentOS-5.6 Continuous Release ( CR ) contiene rpms que serán incluidas en la próxima versión de la rama 5.X de CentOS, pero que debido a que son actualizaciones de seguridad y soluciones a bugs conocidos es recomendable instalarlas sin tener que esperar a que salgan a la luz con la nueva versión 5.7, que saldrá aproximadamente en una semana.

Se recomienda encarecidamente activar estos repositorios y actualizar el sistema. Únicamente hay que instalar los siguientes repos y actualizar el sistema. Como ya sabéis se añadirá el nuevo repositorio CentOS-CR.repo en la ruta /etc/yum.repos.d/. Podéis descargar los rpm a continuación:

i386:

http://mirror.centos.org/centos/5.6/cr/i386/RPMS/centos-release-cr-5-6.el5.centos.1.i386.rpm

md5: 67bbeb40cb77a91379847074667d2956
sha256: 50cd9f3d35b391a9009a9caae80182dcfccfa5abaf4ff4ef5f4d880bcf26b04c

x86_64:

http://mirror.centos.org/centos/5.6/cr/x86_64/RPMS/centos-release-cr-5-6.el5.centos.1.x86_64.rpm

md5: c447f54818a657a9dfd7fdd28a28cfcc
sha256: dab390a0fca17612e438b215fc90448ebcef982e96e25cbea8426f00edc8b7a5

pfSense: Firewall Open Source basado en FreeBSD

Estos días hemos estado probando a nivel local la distribución pfSense, firewall Open Source basado en FreeBSD y que en su día comenzó siendo un fork del proyecto m0n0wall.

La principal función de pfSense es la de ser usado a modo de firewall o router, pero si vamos más allá descubrimos que cumple a la perfección con otras funciones como la de conectividad VPN (IPsec, OpenVPN, PPTP), balanceo de carga, NAT, tabla de estado, posible configuración de failover entre dos nodos físicos pfSense, Dynamic DNS, informacíon vía RRD a tiempo real con gráficas, servidor DHCP y Relay, etc.

Si no disponéis del presupuesto necesario para la adquisición de un buen firewall comercial, dadle una oportunidad a esta distribución. Los requerimientos mínimos son 128 MB de RAM y una de 100 MHz Pentium.

Toda la información sobre pfSense en el sitio web oficial.

pfSense Firewall

Introducción a iptables

firewallMuchos sysadmins estamos acostumbrados a utilizar Frontends del firewall iptables para facilitarnos el trabajo, como por ejemplo APF Firewall. Yo soy uno de ellos. Independientemente de esto, conviene saber como funciona iptables de forma interna para evitar la dependencia de este tipo de aplicaciones de terceros para configurar de forma correcta el firewall del kernel Linux. Vamos a ver algunos puntos que nos ayudarán a comprender su funcionamiento.

Listar reglas, Chain y políticas de Iptables

Con estos comandos podemos ver de un vistazo la configuración establecida en el firewall.

Ver el listado de reglas activas en el firewall:

# iptables -L

Borrar todas las reglas establecidas en el firewall:

# iptables -F

Pone a 0 los contadores de bytes y paquetes:

# iptables -Z

Iptables tiene 3 Chain (cadenas) sobre las cuales construir las reglas, establecer políticas comunes, etc: INPUT, FORWARD y OUTPUT. La política por defecto para ellas es de aceptar todo:

# iptables -L

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

También podemos listar únicamente las reglas y política de una Chain concreta:

# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Si no fuera suficiente estas tres Chain podemos crear nuevas o eliminar podemos hacerlo, así como renombrar las ya existentes:

Crear una nueva Chain llamada TEST:

# iptables -N TEST

Eliminarla:

# iptables -X TEST

Renombrarla a TEST2:

# iptables -E TEST TEST2

Establecer políticas por defecto

Para poder empezar a configurar Iptables debemos partir de una base, una política por defecto que aceptará o denegará el tráfico para cada una de las Chain vistas anteriormente (INPUT OUTPUT o FORWARD). Si quisierais blindar el sistema podríais partir de una base ‘paranoica‘ denegando todo:

# iptables -P INPUT DENY
# iptables -P OUTPUT DENY
# iptables -P FORWARD DENY

En el momento que lo hicierais perderíais toda conectividad en la máquina, así que nosotros vamos a comenzar aceptando todo y aplicando pequeñas restricciones en nuestra máquina, una vez configurado todo es cuando podríamos aplicar la configuración restrictiva de arriba:

# iptables -P INPUT ACCEPT
# iptables -P OUTPUT ACCEPT
# iptables -P FORWARD ACCEPT

Veréis que estamos añadiendo las reglas directamente desde la línea de comandos, lo óptimo es añadirlas dentro de un script para así ejecutarlo todo de forma automática cuando arrancamos el equipo, lo veremos después.

Filtrado de puertos, IPs, rangos…

Una vez establecida la política por defecto, podemos comenzar a definir nuestras reglas específicas para cada cadena (Chain). La estructura del comando usado para filtrado de puertos, ips, etc es la siguiente:

Filtrado/apertura de un puerto/rango de puertos

# iptables -A <INPUT|OUTPUT|FORWARDING> -p <tcp|udp> --dport <PUERTO_DESTINO> -j <ACCEPT|DROP>

Así por ejemplo si quisieramos cerrar el puerto de entrada tcp 21 (FTP) para toda la máquina:

# iptables -A INPUT -p tcp --dport 21 -j DROP

Permitir el tráfico de entrada por el puerto 80, necesario por ejemplo si el equipo es un servidor web:

# iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Para bloquear un rango de puertos, simplemente especificamos el primer y último puerto del rango, en este ejemplo bloqueamos la salida tcp de los puertos 2000 al 3000:

# iptables -A OUTPUT -p tcp --dport 2000:3000 -j DROP

Permitir/denegar puertos a determinadas IPs, interfaces de red o CIDR

# iptables -A <INPUT|OUTPUT|FORWARDING> -s <IP|RANGO> -p <tcp|udp> --dport <PUERTO_DESTINO> -j <ACCEPT|DROP>

Es probable que necesitemos configurar políticas de aceptación o denegación de puertos a determinadas IPs, o incluso el acceso/denegación total a las mismas. La IP la especificaremos con el parámetro -s. Vamos a ver unos ejemplos:

Aceptar todo el tráfico de entrada de una IP:

# iptables -A INPUT -s 192.168.1.128 -j ACCEPT

Denegar todo el tráfico de entrada a una IP:

# iptables -A INPUT -s 192.168.1.128 -j DROP

Aceptar a una IP el acceso a un determinado puerto:

# iptables -A INPUT -s 192.168.1.128  -p tcp --dport 25 -j ACCEPT

Para el tema de rangos, podemos usar la notación CIDR. Vamos a aceptar todo el tráfico en la red local:

# iptables -A INPUT -s 192.168.0.0/24 -j ACCEPT

También podemos especificar reglas restringiendo según interfaces de red en lugar de IPs o rangos. Esto lo hacemos mediante el parámetro -i:

# iptables -A INPUT -i eth0 -j ACCEPT

Nuestro primer script de Iptables

Antes de hacer el script conviene saber qué puertos tenemos abiertos en la máquina para configurarlos previamente y evitar problemas. Podemos usar nmap o netstat para averiguarlo. Un ejemplo de un típico servidor con servicios web, MySQL, correo, etc podría ser el siguiente:

# nmap -sTU localhost

Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2011-08-27 21:14 CEST
Interesting ports on localhost (127.0.0.1):
Not shown: 3152 closed ports
PORT     STATE         SERVICE
1/tcp    open          tcpmux
21/tcp   open          ftp
25/tcp   open          smtp
80/tcp   open          http
110/tcp  open          pop3
143/tcp  open          imap
443/tcp  open          https
465/tcp  open          smtps
783/tcp  open          spamassassin
993/tcp  open          imaps
995/tcp  open          pop3s
3306/tcp open          mysql
161/udp  open|filtered snmp

La salida de nmap nos ofrece una guía clara sobre los puertos a abrir. A partir de aquí es cuestión de construir nuestro script con las reglas correspondientes, estableciendo primero las políticas generales y luego definiendo el filtrado/apertura concreta de puertos, si queremos restringir puertos a determinadas IPs, bloquear el acceso a rangos CIDR, etc.

#!/bin/sh
# Primero limpiamos cualquier regla haciendo un flush
# tambien reseteamos contadores (-Z) y las Chain personalizadas
# que se hayan creado (-X)
iptables -F
iptables -X
iptables -Z

# Politicas por defecto (ACEPTAR TODO)
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

# Cerramos ssh excepto para nuestra red privada
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP

# Tenemos un servidor MySQL pero únicamente para servir en local
iptables -A INPUT -p tcp --dport 3306 -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -j DROP

# Aceptamos todas las conexiones FTP, HTTP y HTTPS
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Servicios de correo
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -p tcp --dport 143 -j ACCEPT
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 465 -j ACCEPT
iptables -A INPUT -p tcp --dport 993 -j ACCEPT
iptables -A INPUT -p tcp --dport 995 -j ACCEPT

# SNMP lo vamos a permitir para nuestra red local
iptables -A INPUT -p udp --dport 161 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p udp --dport 161 -j DROP

# Una vez que hayamos abierto todo lo necesario, podemos cerrar
# el resto o un rango especifico de puertos conocidos...
iptables -A INPUT -p tcp --dport 1:1024 -j DROP
iptables -A INPUT -p udp --dport 1:1024 -j DROP

Este es un ejemplo sencillo (¡ojo, no verificado!) que muestra las posibilidades más básicas de iptables, hay que tener en cuenta que no hemos tratado más que TCP y UDP sobre rasgos generales, no tratamos ICMP ni configuraciones detalladas. Para ello, os emplazo y recomiendo la guía que encontraréis el TLDP (The Linux Documentation Project) o a futuros artículos que complemetarán a este y enlazaré conforme vayamos avanzando.

Consejos para reducir el SPAM en tu correo

SPAMEl Spam es uno de los mayores quebraderos de cabeza tanto para los administradores de sistemas como para el usuario final de Internet, y parece q lo seguira siendo durante un tiempo… Centrándonos en el usuario final, gracias a unos simples consejos podemos reducir el correo basura en nuestras cuentas de correo en un porcentaje muy alto.

  • Registros en sitios web: La mayor parte de los internautas se registran continuamente en foros, blogs, tiendas y todo tipo de webs online, el resultado suele ser que nuestra dirección de correo electrónico queda almacenada en decenas de bases de datos, para posteriormente (en gran parte de los casos) ser usadas para envío de boletines y/o publicidad.Es recomendable en estos casos tener una dirección de correo electrónico alternativa, y usarla para todos estos registros, de este modo nuestro e-mail habitual quedará libre de este tipo de correos.
  • Buzones globales: Este tipo de buzones, también conocido como cuentas atrapalo todo o catch all son uno de los mayores focos de spam. Básicamente, estas cuentas recogen los correos de todas aquellas cuentas de nuestro dominio que reciben emails y no existen.Solución: No utilizar nunca configuraciones de buzón global en nuestras cuentas de correo.
  • Filtros en clientes de correo: La mayor parte de clientes de correo (Outlook, Thunderbird…) cuentan con filtros internos para detectar correos basura. Conviene activarlos
  • Sentido común: Consejo que se suele presuponer y es desgraciadamente poco habitual. Controla a quién das tu dirección e-mail, evita publicarla en foros, sitios web, mantén limpio de virus, troyanos, spyware y demás tu ordenador…

Como podéis observar, son consejos muy básicos, pero eficaces. ¿Algún consejo para añadir?

Operaciones bancarias en Internet de forma segura

Candado Internet

Voy a recopilar una serie de entradas que tenía publicadas en otro blog. En esta primera voy a tratar un tema delicado, las operaciones bancarias a través de Internet.

Dejando a un lado el phising (que abarcaría otro artículo completo), muy a menudo escuchamos, ya sea a través de conocidos o por los medios, que suceden graves delitos relacionados con robos de tarjetas y demás información sensible a través de Internet.

Hoy en día gran parte de los internautas realizan compras online, y podríamos asegurar que un porcentaje realmente elevado no toma ninguna medida de seguridad a la hora de hacerlo. Independientemente de la seguridad que nos pueda ofrecer la tienda online, banco o sitio web contra el que realizamos la operación, no servirán de nada sino hacemos lo mismo en nuestro ordenador.

Mis consejos para realizar operaciones bancarias por Internet de forma segura son los siguientes:

Evitar el pago con tarjeta de crédito, utilizar métodos alternativos.

Cuando hablo de métodos alternativos, no solamente me refiero a pagar por transferencia bancaria u otro medio de pago tradicional. El pago por PayPal está muy extendido por las tiendas online (permite la transferencia de dinero entre usuarios que tengan correo electrónico, sin facilitar ningún dato de tus tarjetas de crédito).

Los keylogger son tu mayor enemigo.

Un Keylogger es un tipo de software que se encarga de registrar las pulsaciones que se realizan en el teclado, para memorizarlas en un fichero y/o enviarlas a través de internet. Se propagan como un virus y están muy extendidos en sistemas con Microsoft Windows. Si tu ordenador está infectado con uno, al teclear tu tarjeta de crédito o cualquier otro dato sensible puedes estar enviandolo por Internet a los delincuentes (quienes almacenan miles de datos bancarios para su utilización de forma ilegal).

La principal solución para combatir un Keylogger es la utilización de un buen antivirus, antispyware y demás herramientas, además de mantener actualizado el sistema siempre con los últimos parches de seguridad.

Uso de un Live-CD.

Soy de la opinión de que el punto número 2 no te dará el 100% de garantías de estar limpio de este tipo de malware, así que os recomiendo utilizar un Live-CD cuando vayáis a efectuar compras online, operaciones bancarias, etc.

Definición de Live-CD (Wikipedia):

Es un sistema operativo (normalmente acompañado de un conjunto de aplicaciones) almacenado en un medio extraíble, tradicionalmente un CD o un DVD (de ahí sus nombres), que puede ejecutarse desde éste sin necesidad de instalarlo en el disco duro de una computadora, para lo cual usa la memoria RAM como disco duro virtual y el propio medio como sistema de archivos.

Esta medida nos garantiza que el sistema está limpio de virus y software malicioso siempre que lo utilicemos. Existen gran variedades de Live-CD GNU/Linux que podemos utilizar para esta tarea, muchos de los cuales únicamente arrancan un navegador (Firefox):

Hay centenares de LiveCD, GoblinX, Frenzy, Mutagenix, Anonym.OS, CDlinux… tenéis una lista completa aquí.

Despídete de Windows

La última regla y también la más radical. Personalmente os recomiendo el uso de un Live-CD o directamente no utilizar Windows a la hora de realizar operaciones bancarias, manejar y guardar información sensible en el PC, etc.

Los virus en GNU/Linux, BSD o Mac OS X están mucho menos difundidos y tus posibilidades de sufrir este problema serán mínimas o nulas. Sé que esto último es muy complicado, pero por lo menos espero que hagáis caso de alguna de las recomendaciones expuestas en este artículo para evitar males mayores.

Permisos especiales (setuid, setgid, sticky bit)

En Unix existen tres bits de permisos especiales que pueden ser asignados a directorios y/o ficheros ejecutables, setuid (set user information), setgid (set group information) y sticky.

setuid

EL bit setuid es asignable a ficheros ejecutables, y permite que cuando un usuario ejecute dicho fichero, el proceso adquiera los permisos del propietario del fichero ejecutado. El ejemplo más claro de fichero ejecutable y con el bit setuid el

su

.

su

sirve para ejecutar una shell con identificadores de grupo y de usuario distintos al nuestro, por ello ha de tener este bit y así permitir adquirir al usuario temporalmente permisos administrativos para poder hacer el cambio de usuario.

Podemos ver que el bit está asignado (s) haciendo un ls:

$ ls -l /bin/su
-rwsr-xr-x 1 root root 31012 2009-04-04 07:49 /bin/su

Para asignar este bit a un fichero:

# chmod u+s /bin/su

Y para quitarlo:

# chmod u-s /bin/su

Lógicamente, conviene utilizar este bit con extremo cuidado ya que puede provocar una escalada de privilegios en situaciones inseguras. Para que veáis un ejemplo de lo que se podría hacer.

El usuario “alex” no tiene permisos para ejecutar correctamente un fdisk -l:

alex@linux:~$ fdisk -l

La salida es 0, pero si asignamos el bit setuid al binario de fdisk…

# ls -l /sbin/fdisk
-rwsr-xr-x 1 root root 93048 2009-02-18 20:43 /sbin/fdisk

Probamos de nuevo a ejecutar fdisk con el usuario “alex” y conseguimos privilegios de root:

alex@linux:~$ fdisk -l

Disco /dev/sda: 160.0 GB, 160041885696 bytes
255 cabezas, 63 sectores/pista, 19457 cilindros
Unidades = cilindros de 16065 * 512 = 8225280 bytes
Identificador de disco: 0x000c3c51

Dispositivo Inicio    Comienzo      Fin      Bloques  Id  Sistema
/dev/sda1   *           1        3232    25959424    7  HPFS/NTFS
/dev/sda2            3233        9683    51817657+  83  Linux
/dev/sda3            9684        9855     1381590   82  Linux swap / Solaris
/dev/sda4            9856       19457    77128065   83  Linux

Luego nos acordamos de volver a quitarlo:

# chmod u-s /sbin/fdisk

setgid

Si el bit setuid permitía que el proceso adquiriera los permisos del propietario del fichero ejecutado, setgid hace lo mismo pero adquiriendo los privilegios del grupo asignado al fichero, también es asignable a directorios. Este bit entonces será muy útil cuando varios usuarios de un mismo grupo necesiten trabajar con recursos dentro de un mismo directorio.

En el siguiente ejemplo asignamos el bit setgid la carpeta /compartido, le asignamos permisos totales para el propietario y el grupo (770) y el bit segid (2):

$ mkdir compartido && chmod 2770 /compartido

Si hacemos un ls veremos el bit asignado:

$ ls -l
drwxrws--- 2 alex alex      4096 2011-04-24 21:27 compartido

Ahora vamos a hacer la prueba de crear un fichero dentro del directorio. Lo vamos a crear estando autenticados como root, pero al tener el bit setgid le asignará el grupo “alex” en lugar de root.

$ su
# touch test
root@sistemas:/home/alex/compartido# ls -l
total 0
-rw-r--r-- 1 root alex 0 2011-04-24 21:28 test
# whoami
root

En lugar de modo octal podéis asignar también los permisos setgid del siguiente modo:

$ chmog g+s /compartido

Y quitarlo:

$ chmog g-s /compartido

sticky

Este bit suele asignarse en directorios a los que todos los usuarios tienen acceso, y permite evitar que un usuario pueda borrar ficheros/directorios de otro usuario dentro de ese directorio, ya que todos tienen permiso de escritura. Seguro que lo estáis pensando, este bit se asigna siempre en /tmp y /var/tmp.

tmp tiene permisos 777, el bit sticky se asignaría del siguiente modo:

# chmod 1777 /tmp

También así:

chmod o+t /tmp

Y para quitarlo:

chmod o-t /tmp

Si hacemos un ls veremos la “t” asignada:

drwxrwxrwt  13 root root  4096 2011-04-24 20:55 tmp

Esta es una visión general de estos tres bits especiales asignables a ficheros ejecutables y directorios en Unix/Linux.

Cómo integrar pure-ftpd y clamav para buscar virus en subidas FTP

Con unos sencillos pasos (esta entrada está basada en este artículo de wiki.cpaneldirect.net) es posible integrar el servidor ftp pure-ftpd con el antivirus clamav. Gracias a esto automatizaremos la revisión en busca de virus en todos los ficheros que se suban por FTP.

Lo primero que debemos hacer es instalar clamav. Si el sistema es RHEL, CentOS, etc podemos instalarlo por yum (tendremos que tener el repositorio DAG):

# yum install clamav

Damos por supuesto que pure-ftpd está instalado y configurado, así que entramos directamente en materia. Lo primero es modificar la configuración de pure-ftpd y habilitar la llamada de scripts cuando se realicen subidas al servidor:

# vim /etc/pure-ftpd.conf

Descomentamos la línea CallUploadScript yes:

# If your pure-ftpd has been compiled with pure-uploadscript support,
# this will make pure-ftpd write info about new uploads to
# /var/run/pure-ftpd.upload.pipe so pure-uploadscript can read it and
# spawn a script to handle the upload.

CallUploadScript yes

Ahora tenemos que modificar el script de arranque de pure-ftpd para añadir la llamada al binario encargado de esta tarea (pure-uploadscript).

Justo debajo de la línea (sección START):

$DAEMONIZE $fullpath /etc/pure-ftpd.conf -O clf:/var/log/xferlog $OPTIONS --daemonize

Añadimos:

$DAEMONIZE /usr/sbin/pure-uploadscript -B -r /var/run/pure-ftpd/clamscan.sh

Y justo debajo de esta (sección STOP):

kill $(cat /var/run/pure-ftpd.pid)

Añadimos esta:

kill $(cat /var/run/pure-ftpd/pure-uploadscript.pid)

Ahora creamos el script encargado de revisar los ficheros en busca de virus, lo llamaremos /var/run/pure-ftpd/clamscan.sh, y contendrá lo siguiente.

#!/bin/sh

# /usr/local/bin/clamdscan is faster if clamd is running
CLAMLOC='/usr/local/bin/clamscan';

if [ ! -x $CLAMLOC ]; then
        echo 'clamscan not found';
        exit;
fi
if [ "$1" = "" ]; then
        echo 'Variable is blank';
        exit;
fi
if [ ! -f "$1" ]; then
        echo "$1 file not found"
        exit;
fi

# maybe you would prefer --move=/DIRECTORY instead of remove
$CLAMLOC --remove $1

Como podéis ver, en este script los ficheros que se detecten como maliciosos se eliminan, si queremos que los mueva a una ruta distinta en lugar de borrar usamos –move=/DIRECTORY.

Personalmente veía de gran utilidad que me avisara por correo electrónico, así que podéis usar esta variación del script si queréis en la que el fichero no se toca y si se detecta que es un virus se avisa por correo:

#!/bin/bash
# /usr/local/bin/clamdscan is faster if clamd is running
CLAMLOC='/usr/bin/clamscan';

if [ ! -x $CLAMLOC ]; then
        echo 'clamscan not found';
        exit;
fi
if [ "$1" = "" ]; then
	echo 'Variable is blank';
	exit;
fi
if [ ! -f "$1" ]; then
	echo "$1 file not found"
	exit;
fi
EMAIL="test@micorreo.com"  # Aqui pon tu dirección de correo electronico

# maybe you would prefer --move=/DIRECTORY instead of remove
$CLAMLOC $1 2>/dev/null | grep "FOUND"
if [ "$?" == "0" ]; then
        echo "Script $1 subido por $UPLOAD_USER." | mail -s "[$(hostname)] Upload de fichero malicioso" $EMAIL
fi

Modificamos los permisos del script a 755:

# chmod 755 /var/run/pure-ftpd/clamscan.sh

Y reiniciamos pure-ftpd:

# /etc/init.d/pure-ftpd restart

Ahora solo queda esperar o probar, podéis subir por FTP un fichero malicioso (shell en php, código ofuscado, etc) para verificar el funcionamiento.