Siguiente: FTP invitado
Subir: El servicio FTP
Anterior: El servicio FTP
Índice General
Los problemas relacionados con la seguridad del servicio FTP son
especialmente preocupantes cuando se trata de configurar un servidor de
FTP anónimo; muchos de estas máquinas situadas en universidades
españolas se convierten en servidores de imágenes pornográficas o de
warez (copias ilegales de programas comerciales). Conseguir un servidor
de FTP anónimo seguro puede llegar a ser una tarea complicada: incluso en las
páginas de ayuda de algunas variantes de Unix (como Solaris) se trata de
facilitar el proceso para el administrador mediante un shellscript que
- por defecto - presenta graves problemas de seguridad, ya que deja una
copia del fichero de claves del sistema como un archivo de acceso público y
anónimo.
Para configurar correctamente un servidor de este tipo necesitamos
en primer lugar crear al usuario ftp en /etc/passwd y /etc/shadow, así como su directorio de conexión (algunos Unices, como
Linux, ya incorporan esto al instalar el sistema). Este directorio ha de
pertenecer a root (ningún fichero o subdirectorio ha de
pertenecer nunca a ftp) y al grupo al que pertenece
ftp: con esto conseguimos que los permisos de propietario sean para el
administrador y los de grupo para los usuarios anónimos; estos permisos
serán 555.
Dentro del $HOME de ftp hemos de crear el árbol de directorios
mínimo para poder trabajar correctamente; esto es debido a la llamada a
chroot() que se utiliza en los accesos anónimos, que permite a esos
usuarios ver el directorio raíz de su conexión en el directorio real
~ftp/. Al menos dos directorios son necesarios: etc/ y bin/, ambos propiedad de root y con modo 111. En el primero de ellos
hemos de crear un fichero passwd y otro group, utilizados no
con propósitos de autenticación sino para visualizar el propietario y grupo
de cada fichero en el entorno sobre el que se ha aplicado chroot() al
ejecutar ls: por
tanto, no hace falta ninguna contraseña en ese fichero passwd,
y sólo ha de contener entradas para los usuarios que posean ficheros bajo
la jerarquía de ftp, como root; de la misma forma, el fichero
group sólo ha de contener las entradas correspondientes a grupos que
posean ficheros en dicha jerarquía:
anita:~# cat /export/home/ftp/etc/passwd
root:*:0:1:El Spiritu Santo:/:/sbin/sh
anita:~# cat /export/home/ftp/etc/group
root::0:
other::1:
daemon::2:
ftp::30000:
anita:~#
Como vemos, el usuario ftp tiene un shell denominado /bin/false; aunque aquí no tiene ningún efecto, en el archivo de
contraseñas real de la máquina esto es útil para prevenir que dicho
usuario pueda conectar mediante TELNET o similar.
Por su parte, en el otro directorio que hemos creado (bin/) hemos de
almacenar una copia del programa ls, de forma que los usuarios puedan
listar los contenidos de los directorios cuyos permisos lo permitan; si
utilizamos una versión estática del programa, como hace por ejemplo Linux,
no hemos de configurar nada para que la aplicación funcione, pero si en
cambio utilizamos un ls dinámico (como SunOS o Solaris) hemos de
crear el directorio lib/ dentro de ~ftp/ y copiar en él las
librerías necesarias para que el programa funcione (podemos ver de cuáles
se trata con ldd).
Con estos pasos ya tenemos configurada la base de nuestro servidor de FTP anónimo; no obstante, es habitual crear dos directorios más, uno
denominado pub/ y otro incoming/, dentro de la misma jerarquía
que los anteriores (esto es, en el $HOME del usuario ftp). El
primero suele contener directorios con todos los ficheros que deseemos ofrecer
a los usuarios anónimos; su modo ha de ser 555, o 2555 en los sistemas
que utilicen el bit setgid en un directorio para que sus subdirectorios y
ficheros hereden el grupo del propietario. El directorio incoming es
justo lo contrario: sirve para que esos usuarios anónimos puedan enviar
archivos a nuestra máquina. Y es aquí donde suelen comenzar muchos
problemas: al permitir el upload de software, es posible que algunos
piratas utilicen nuestra máquina para crear servidores warez, subiendo
programas comerciales a este directorio y luego indicando su localización
exacta a otras personas, para que los puedan descargar. Por tanto, los permisos
de incoming son vitales para nuestra seguridad (incluso si no deseamos
que los usuarios anónimos nos envíen ficheros podemos borrar este
directorio): esos permisos han de ser 1733, y el propietario del directorio es
el root. >Para qué ponemos el bit de permanencia? Muy sencillo: para
que los usuarios no puedan sobreescribir o borrar ficheros existentes; aunque
la mayoría de servidores FTP no permiten a los usuarios anónimos
sobreescribir ficheros, si no pusiéramos este modo un usuario normal del
sistema sí que podría hacerlo.
El siguiente shellscript puede utilizarse para configurar cómodamente
un entorno restringido destinado a los usuarios de FTP anónimo
siguiendo las directrices que acabamos de comentar; funciona correctamente
(en teoría) sobre Solaris, Linux y AIX15.3. Al igual que sucede con muchas tareas automatizadas, conviene
repasar manualmente la estructura de directorios y ficheros creados para
comprobar que todo es como esperábamos:
anita:~# cat /usr/local/sbin/creaentorno
#!/bin/sh
# Script para crear un entorno chroot()eado.
# Funciona OK en Linux, Solaris y AIX.
#
# Esta variable es una lista con los programas que necesitamos en el
# entorno restringido.
PROGS="/bin/ls"
# Imprime modo de uso
if (test $# -lt 1); then
echo "Usage: $0 /path/to/chroot-environment"
exit
fi
# Detectamos clon de Unix
OS=`uname -s`
# Creamos estructura de directorios
echo "Creando estructura de directorios para $OS"
if [ ! -d $1 ]; then
mkdir -p $1
fi
chown root $1
for i in bin etc; do
if [ ! -d $1/$i ] ; then
mkdir -p $1/$i
fi
chown root $1/$i
done
# En funcion del Unix, la estructura sera una u otra...
if [ $OS = "Linux" ]; then
if [ ! -d $1/lib ]; then
mkdir -p $1/lib
fi
chown root $1/lib
fi
if ( test $OS = "SunOS" || test $OS = "AIX" ); then
if [ ! -d $1/usr/lib ]; then
mkdir -p $1/usr/lib
fi
chown root $1/usr/lib
cd $1
ln -s ./usr/lib $1/lib
fi
# Instalamos programas y las librerias que necesitan
echo "Instalando programas y librerias..."
for i in $PROGS; do
if [ ! -f $1/$i ]; then
cp $i $1/bin
fi
chmod 111 $1/bin
chown root $1/bin
if [ $OS = "AIX" ]; then
for j in `ldd $i|awk -F"(" '{if(NR!=1) print $1}'`; do
if [ ! -f $1/$j ]; then
cp $j $1/lib
fi
chown root $1/$j
done
else
for j in `ldd $i|awk '{print $3}'`; do
if [ ! -f $1/$j ]; then
cp $j $1/lib
fi
chown root $1/$j
done
fi
done
# Estos ficheros quizas sea necesario retocarlos a mano, en funcion del tipo
# de entorno restringido que fabriquemos.
# Generamos PASSWD
echo "Generando /etc/passwd..."
awk -F: '$1=="root" {print $1":*:"$3":"$4":"$5":"$6":"$7}' /etc/passwd >\
$1/etc/passwd
awk -F: '$1=="bin" {print $1":*:"$3":"$4":"$5":"$6":"$7}' /etc/passwd>>\
$1/etc/passwd
awk -F: '$1=="daemon" {print $1":*:"$3":"$4":"$5":"$6":"$7}' /etc/passwd>>\
$1/etc/passwd
chmod 444 $1/etc/passwd
chown root $1/etc/passwd
# Quizas hay que anyadir otros grupos que nos interesen
# Generamos GROUP con algunas entradas
echo "Generando /etc/group..."
awk -F: '$1=="root" {print $1":*:"$3":"$4}' /etc/group>$1/etc/group
awk -F: '$1=="bin" {print $1":*:"$3":"}' /etc/group>>$1/etc/group
awk -F: '$1=="daemon" {print $1":*:"$3":"}' /etc/group>>$1/etc/group
chmod 444 $1/etc/group
chown root $1/etc/group
# Generamos pub/ e incoming/
echo "Generando pub/ e incoming/..."
if [ ! -d $1/pub ]; then
mkdir -p $1/pub
fi
chmod 2555 $1/pub
chown root $1/pub
if [ ! -d $1/incoming ]; then
mkdir -p $1/incoming
fi
chmod 1733 $1/incoming
chown root $1/incoming
# Si estamos en Solaris, aun no hemos acabado
if [ $OS = "SunOS" ]; then
# Mas librerias
echo "$OS: Instalando librerias..."
for i in ld.so.1 libc.so.1 libdl.so.1 libmp.so.2 libnsl.so.1 \
libsocket.so.1 nss_compat.so.1 nss_dns.so.1 nss_files.so.1 \
nss_nis.so.1 nss_nisplus.so.1 nss_xfn.so.1 straddr.so \
straddr.so.2; do
cp /usr/lib/$i $1/usr/lib
done
if [ ! -d $1/dev ]; then
mkdir -p $1/dev
fi
chown root $1/dev
# Generamos dispositivos
echo "$OS: Generando dispositivos..."
for i in /dev/zero /dev/tcp /dev/udp /dev/ticotsord; do
MAJOR=`ls -lL $i|awk '{print $5}'|sed s/","//g`
MINOR=`ls -lL $i|awk '{print $6}'`
TYPE=`ls -lL $i|cut -c1-1`
/usr/sbin/mknod $1/$i $TYPE $MAJOR $MINOR
done
chmod 666 $1/dev/*
fi
echo "FIN"
# FIN de Solaris
anita:~#
Algunos problemas relacionados con incoming/ provienen de los permisos
con que se
crean sus ficheros y subdirectorios: aunque los usuarios anónimos no puedan
leer el directorio, con algunos servidores ftpd sí que es posible
que puedan leer los ficheros contenidos en él (y sus subdirectorios), con lo
que sigue siendo posible acceder a los archivos conociendo su nombre exacto;
para evitar este problema, muchos administradores planifican un sencillo
shellscript para que cada cierto tiempo mueva los contenidos de incoming a otro lugar, fuera del alcance de los usuarios anónimos (por
ejemplo, un subdirectorio con modo 000 de /tmp/). Ciertos servidores,
como WU-ftpd, tienen un fichero de configuración (/etc/ftpaccess) donde indicar - entre otras cosas - los modos con que se van
a crear entradas en incoming/.
Un ataque típico a los servidores de FTP es una negación de
servicio llenando todo el espacio disponible para el upload de ficheros;
para minimizar las consecuencias de este ataque, es conveniente situar el
directorio ~ftp/ en una partición separada del resto del sistema
de ficheros, donde sólo se encuentre dicho directorio; algunos demonios
permiten directamente limitar la cantidad de ficheros subidos al servidor en
cada sesión.
Otra negación de servicio muy habitual contra los servidores de FTP
anónimo es obligar a las máquinas a consumir una excesiva cantidad de
CPU, ralentizando el sistema hasta que la calidad de servicio es muy baja; esto
se produce en servidores que permiten descargar directorios completos como un
único archivo, empaquetados con tar y/o comprimidos con gzip.
Veamos un ejemplo extraído de una sesión de FTP anónimo:
ftp> pwd
257 "/pub/utils" is current directory.
ftp> ls
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
total 377
drwxr-xr-x 2 root root 1024 Sep 18 22:28 .
drwxrwxr-x 3 root wheel 1024 Sep 18 22:28 ..
-rw-r--r-- 1 root root 163519 Sep 18 22:28 transfig-3.1.2.tar.gz
-rw-r--r-- 1 root root 217850 Sep 18 22:27 tth_C.tgz
226 Transfer complete.
ftp> cd ..
250 CWD command successful.
ftp> pwd
257 "/pub" is current directory.
ftp> ls
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
total 3
drwxrwxr-x 3 root wheel 1024 Sep 18 22:28 .
drwxrwxr-x 8 root wheel 1024 Aug 1 1994 ..
drwxr-xr-x 2 root root 1024 Sep 18 22:28 utils
226 Transfer complete.
ftp> get utils.tar.gz
local: utils.tar.gz remote: utils.tar.gz
200 PORT command successful.
150 Opening BINARY mode data connection for /bin/tar.
226 Transfer complete.
381369 bytes received in 1.07 secs (3.5e+02 Kbytes/sec)
ftp>
Como podemos ver, acabamos de descargar un directorio completo empaquetado y
comprimido sin más que añadir al nombre de dicho directorio la extensión
.tar.gz (o simplemente .tar si no hubiéramos querido comprimirlo).
Evidentemente esto resulta muy útil en determinadas situaciones pero, >nos
hemos parado a pensar que sucedería si alguien intentara descargar el
directorio /pub.tar.gz en un servidor con unos cuantos Gigabytes
de ficheros? La carga del sistema crecería muchísimo, ya que estamos
empaquetando y comprimiendo un archivo de grandes dimensiones; si ahora
extendemos esto a varios usuarios que ejecutan la misma orden
simultáneamente podemos hacernos una idea de la sobrecarga introducida en la
máquina: una razón más que suficiente para tener cuidado con los
directorios que permitimos descargar de esta forma...
Por último, es una buena idea mostrar un mensaje cuando los usuarios
anónimos conectan a nuestra máquina donde se indiquen claramente los fines
del sistema y la atención a su uso indebido; este mensaje puede sernos útil
tanto con fines jurídicos (así el atacante no podrá argumentar que
desconocía la finalidad del sistema) como con fines disuasorios: si el
pirata se da cuenta de que nos preocupamos por la seguridad de nuestro servidor,
es posible que lo abandone y busque otro menos protegido. Por ejemplo, si
utilizamos WU-ftpd, en ~ftp/welcome.msg podemos escribir el
mensaje mostrado al conectar al sistema, y en diferentes ficheros .message el mensaje que se vuelca a acceder a un directorio (estos nombres son
configurables en /etc/ftpaccess). Un ejemplo del mensaje de entrada puede
ser el siguiente:
anita:~# cat /export/home/ftp/welcome.msg
* * * ANITA * * *
----------- Bienvenid@s a ANITA ------------
Esta maquina es propiedad de la Universidad Politecnica de Valencia y
sus fines son exclusivamente academicos y de investigacion. Cualquier
otro uso sera perseguido y castigado con el maximo rigor.
Cualquier actividad realizada en, desde o hacia este sistema esta
sujeta a monitorizacion sin previo aviso.
anita:~#
Siguiente: FTP invitado
Subir: El servicio FTP
Anterior: El servicio FTP
Índice General
2003-08-08