FTP (Protocolo de transferencia de ficheros) es un protocolo de red para la transferencia de ficheros sobre redes TCP/IP que usa habitualmente los puertos 20 y 21. Es un protocolo antiguo, anterior a la generalización de la red y los problemas de seguridad derivados de ella. Por eso, al igual que ocurre con telnet, no ofrece cifrado ni seguridad y el nombre de usuario y la contraseña para establecer sesión viajan en claro a través de la red.
Data de 1971 cuando se desarrolló para transferir archivos entre equipos del MIT (Instituto Tecnológico de Massachussets) y su forma actual se perfiló prácticamente en 1973.
Se halla definido en el RFC 959.
El protocolo sigue el modelo cliente-servidor en la que una máquina se encarga de hacer las peticiones (el cliente) y la otra de recibirlas y satisfacerlas (el servidor). Para ello, durante una conexión FTP se establecen dos canales:
La existencia de estos dos canales supone que tanto en el cliente como en el servidor deban existir dos procesos:
Por supuesto, el protocolo es independiente de los sistemas de ficheros que haya en el servidor y el cliente.
Cuando se inicia una conexión el PI del cliente establece una conexión con el servidor de modo similar a como se hace en el protocolo telnet. Mediante el PI el cliente es capaz de enviar órdenes al del servidor. Ahora bien, es necesario también establecer el canal de datos por el cual se transferirán los ficheros. La forma en que se establece la conexión depende del modo que se escoja:
Pero ¿por qué existen estos dos modos? El modo original de conexión era el modo activo (o modo normal). El problema de este modo es que el canal de datos no es establecido por el cliente (como sucede habitualmente en las relaciones cliente-servidor), sino que es establecido por por el servidor. Esto implica que el cliente debe permitir conexiones entrantes aleatorias a cualquiera de sus puertos no reservados, cuando lo habitual es que sólo se permita a los clientes iniciar conexiones y mantener conexiones ya establecidas. Por ese motivo lo más probable es que, si existe un cortafuegos, éste malogre el establecimiento del canal de datos y no se pueda intercambiar la información. El modo pasivo en cambio implica que ambos canales (el de control y el de datos) son establecidos siempre por el cliente.
Actualmente existen clientes ftp con interfaz gráfica que abstraen de la interfaz de comandos que está sociada al PI. No obstante, se siguen usando los clientes no gráficos y puede darse el caso de que no se pueda disponer de uno gráfico en algún momento. Como los sistemas operativos suelen incluir un cliente sin interfaz gráfica, tiene cierto interés conocer los comandos que pueden introducirse en el protocolo.
La comunicación comienza cuando un cliente establece la comunicación con un servidor que normalmente escucha en el puerto 21:
ftp ftp.servidor.com
Normalmente la conexión es así, aunque quizás sea necesario especificar el puerto de conexión, si el administrador del servidor cambió el número de puerto para el canal de control. También es posible no especificar el nombre del servidor. En este caso desde el PI del cliente deberemos usar el comando open para establecer la conexión.
Inmediatamente el servidor pedirá que nos autentificamos con un usuario que exista en el servidor, por lo cual deberemos conocer un nombre deusuario y una contraseña. Sin embargo, existen servidores ftp que permiten el acceso anónimo que consiste en que la validación se realiza introduciendo como nombre de usuario anonymous y como contraseña una dirección de e-mail. Si el cliente no pide ninguna contraseña, el comando user permite especificar el usuario.
Una vez establecida la conexión y autentificados, se pueden usar el comando help para obtener información de los distintos comandos disponibles.
Ha de hacerse notar que en los clientes ftp se puede especificar si el fichero será un fichero de texto (comando ascii) o no (comando binary). Esto es debido al modo en que se codifican los finales de línea en los distintos sistemas operativos.
Se procederá a la instalación de vsftpd en debian. El servidor tiene fama de ser seguro y soporta el enjaulado de usuarios (es decir, que no puedan salir de su propio directorio) y certificado ssl para cifrar la conexión.
Basta con usar aptitude:
# aptitude install vsftpd
La configuración por defecto es muy pobre: sólo deja entrar al servidor ftp dentro de /home/ftp como usuario anónimo y descargar ficheros.
El fichero de configuración es /etc/vsftpd.conf
. Opciones interesantes de este fichero son:
Obviamente ante cualquier cambio en la configuración se debería reiniciar el servidor:
# /etc/init.d/vsftpd restart
El usuario anónimo tiene como directorio personal /srv/ftp, pero en principio sólo tiene habilitado el permiso de lectura. Si queremos que pueda subir debemos poner en el fichero de configuración:
anonymous_enable=YES write_enable=YES anon_upload_enable=YES
Sin embargo, esto no es suficiente, porque el usuario anónimo que en es el usuario del sistema ftp no tiene permisos de escritura sobre /srv/ftp. De hecho, debian hace propietario de ftp a root. Cambiemos esto:
# chown ftp:nogroup /srv/ftp
Ahora si se intenta entrar como anónimo, el servidor ftp rechazará la conexión porque se niega a conectar si el usuario ftp tiene permisos de escritura sobre su propio directorio. La solución es crear un subdirectorio donde ftp sí tenga permisos de escritura y luego quitar el permiso de escritura sobre /srv/ftp:
# mkdir /srv/ftp/incoming # chown ftp:nogroup /srv/ftp/incoming #chmod u-w /srv/ftp
En principio basta con indicarlo con una opción:
local_enable=YES
Ahora bien, si se quiere enjaularlos:
chroot_local_user=YES
Por último si se quiere hacer alguna excepción al enjaulado:
chroot_list_enable=YES
que permite incluir estas excepciones en el fichero /etc/vsftpd.chroot_list. Por ejemplo:
# echo "usuario_liberrimo" > /etc/vsftpd.chroot_list
Si se quiere cambiar el nombre de este fichero, puede usarse la directiva:
chroot_list_file=/etc/vsftpd.no_enjaulados
Sobre chroot_list_enable ha de hacerse una puntualización importante: en realidad, esta directiva habilita la existencia de un fichero de excepciones a la norma general. Así pues, si chroot_local_user está como NO, la directiva también tiene efecto, pero los usuarios enumerados en el fichero serán los únicos que estarán enjaulados.
Una última directiva muy relacionada con los usuarios locales es user_config_dir. Esta directiva permite indicar un directorio dentro del cual se podrán incluir opciones limitadas a un usuario determinado. Para hacerlo basta definir la directiva:
user_config_dir /etc/vsftpd
y crear dentro de este directorio ficheros con el nombre de cada usuario, dentro del cual se incluirán las directivas que queremos que sólo afecten a este usuario. Por ejemplo:
# echo "local_max_rate 1024" > /etc/vsftpd/pepe
limitará la velocidad de transferencia del usuario pepe a 1 Kb/s.
En las versiones más recientes de vsftpd enjaular los usuarios dentro de su propio directorio (circunstancia por otra parte muy común si son usuarios reales del sistema) provoca un error, ya que por razones de seguridad vsftpd se niega a enjaular un usuario dentro de un directorio en el que el propio usuario tenga permisos de escritura. Para soslayar esta limitación podemos seguir varias estrategias:
Tanto la segunda como la tercera opción, exigen cambiar el directorio de acceso al ftp, acción que se explica más adelante.
Es posible limitar el acceso al servidor según el usuario que intente autentificarse:
userlist_enable=YES userlist_file=/etc/vsftpd.userlist
Esto permite indicar en el fichero vsftpd.userlist una lista negra de usuarios que no podrán acceder al servidor. Si se añade:
userlist_deny=NO
entonces la lista pasa a ser una lista blanca: sólo los usuarios que aparezcan dentro de él podrán identificarse.
No obstante lo anterior, es más versátil permitir o restringir el acceso al servidor modificando el fichero /etc/pam.d/vsftpd.
De modo predeterminado un usuario, al identificarse ante vsftpd, accede a su directorio personal. Pero existen modos de cambiar esto.
La directiva local_root que modifica el directorio de acceso del usuario:
local_root=/srv/ftp
Nótese que esto se puede poner en conjunción con user_config_dir para que la directiva local_root afecte sólo a determinados usuarios.
Más útil aún es usar la directiva user_sub_token, del siguiente modo:
user_sub_token=$USER local_root=/srv/ftp/$USER
De este modo, cada usuario tendrá un directorio personal que incluye su propio nombre. Esto tiene cierta utilidad para usuarios virtuales, pero esta misma directiva puede ayudarnos a soslayar el problema de que los usuarios reales no puedan estar enjaulados en un directorio del que tienen permisos de escritura. Para ello, podemos crear un subdirectorio ftp dentro del directorio personal de cada usuario:
$ mkdir -p ftp/uploads $ chmod 440 ftp
Esta operación hemos supuesto que la ha hecho el propio usuario. Además ha creado un subdirectorio uploads en el que sí tiene permisos de escritura, a fin de tener la posibilidad de subir ficheros al servidor. Hecho esto la configuración de vsftpd podría ser esta:
user_sub_token=$USER local_root=/home/$USER/ftp
La directiva passwd_chroot_enable:
passwd_chroot_enable=YES
Poner esta directiva a YES tiene un efecto curioso. El servidor determinará el directorio del usuario leyendo cuál tiene definido en /etc/passwd, pero parará de leer cuando detecte la secuencia /./. Así, por ejemplo, si en el fichero passwd existiese un usuario definido así:
pepe:x:1001:1001:Pepito Piscinas,,,:/home/pepe/ftp/./..:/bin/false
El directorio personal para el sistema sería /home/pepe, puesto que acabamos haciendo .. para volver al directorio padre. Sin embargo, vsftpd pararía de leer al llegar a /./, así que para este usuario el directorio de ftp sería /home/usuario/ftp.
Para ello es necesario crear primero un certificado que incluya la clave pública y la privada:
# openssl req -x509 -nodes -days 730 -newkey rsa:1024 -keyout /etc/ssl/private/vsftpd.key -out /etc/ssl/certs/vsftpd.crt
Esto crearía una clave con 2 años de validez (730 días). Además habrá que habilitar el cifrado en el fichero de configuración:
ssl_enable=YES allow_anon_ssl=NO force_local_data_ssl=NO force_local_logins_ssl=YES ssl_tlsv1=YES ssl_sslv2=NO ssl_sslv3=NO rsa_cert_file=/etc/ssl/certs/vsftpd.crt rsa_private_key_file=/etc/ssl/private/vsftpd.key
Con esta configuración se forzaría el cifrado de la contraseña, pero no de los datos. Una vez hecho esto ha de hacerse notar que existen dos métodos para el ftp sobre ssl el más antiguo llamado ftp con ssl implícito y el ftp con ssl explícito. El primero implica que el cliente se conecte a distinto puerto dependiendo de si se quiere una conexión cifrada o no; en el segundo en cambio la conexión se recliza por el puerto 21 y hay una negociación previa. vsftpd implementa el segundo método lo cual determina como vayamos a usar el cliente: el cliente ftp tradicional no tiene soporte ssl, pero puede usar ftp-ssl, que viene en un paquete independiente con ese nombre. Si se opta por usar lftp, hay que saber que no hay que declarar que el protocolo es ftps (lo cual debe hacerse cuando la conexión es con ftp implícito. Con el cliente filezilla hay que usar el protocolo ftpes (que se corresponde al explícito, ya que ftps también representa el implícito).
Actualizado por última vez el 28-07-2015.