miércoles, 22 de septiembre de 2010

¿Como funciona el FTP?

Sucede a menudo dentro de redes corporativas con políticas mas o menos paranoicas, que alguien trata de acceder a algún sitio de la web y lo consigue. Luego trata de descargarse una aplicación que necesita para terminar ese proyecto en el que trabaja hace meses y casi pero ups! Termina viendo como el sistema queda levitando sin llegar nunca siquiera a iniciar la bendita descarga. Si consideramos que el estándar para transferencias de archivos dentro de internet es el protocolo FTP (RFC 959, si no saben que es una RFC y no hablo del Registro Federal del Contribuyente, vayan aquí, si alguna vez piensan dedicarse a programar sobre TCP/IP terminarán recitando RFCs) y que además la mayoría de la gente lo ha usado un millón de veces sin siquiera saber que lo hizo, entonces puede que les interese este post.....

Como el protocolo Telnet, FTP fue diseñado desde un inicio para trabajar entre hosts diferentes, entre diferentes sistemas operativos, usando estructuras diferentes de archivos y probablemente diferentes sets de caracteres. Pero FTP resuelve toda esta heterogeneidad usando un enfoque diferente a telnet (que obliga a los dos extremos a lidiar con un estándar unico el NVT, usando ASCII de 7 bits), FTP soporta un número limitado tanto de tipos como de estructuras de arhivos. FTP opera usando el servicio de transporte TCP (que es orientado a conexión) para asegurar confiabilidad (aunque transmita los datos enviando datagramas IP, que es un protocolo al que le vale un pepino la conexión ¿como lo hace? eso por si solo amerita otro post pero en adelanto, asi funciona la suite TCP/IP completa , lindo verdad?)
Pero ahora viene el truco (y uno de los conceptos críticos para enteder el protocolo), a pesar de que FTP usa TCP como muchas otras aplicaciones, no solo usa una conexión como los otros sino dos. El modelo esta designado alrededor de dos canales lógicos de comunicación (dos sockets) establecidos entre servidor y cliente, una conexión de control, que es creada cuando se inicia la sesión, perdura hasta que es cerrada y es usada para transferir información de control, como comandos (y no para transferir archivos) y otra conexión de datos que es establecida con cada dato enviado en cualquiera de las dos direcciones. La figura abajo ilustra el modelo: 
Procesos involucrados en una conexión FTP
 El esquema muestra un par de detalles interesantes. Primero que el usuario normalmente no tiene que tratar con los comandos y réplicas intercambiados  a través de la conexión de control (esos detalles se los deja a los dos Intérpretes de protocolo). El bloque Interface de usuario representa lo que sea que el usuario use como cliente, puede ser la linea de comandos, puede ser Filezilla o puede ser el resto de los (muchos) que hay disponibles y sera quien genere los comandos FTP que serán enviados a través de la conexión de control. De manera similar las réplicas enviadas por el servidor son convertidas al formato que corresponda segun la interface usada.
El segundo detalle es que las funciones de transferencia de datos también son invocadas por los dos intérpretes.  
Un detalle que no muestra la figura es que el puerto usado para la conexión de control es el 21 (del lado servidor, es claro, el cliente usa un puerto cualquiera, o casi, usa un puerto efímero), y esto es siempre, lo que no es siempre es que se use el 20 para transferencias de datos (como veremos mas adelante).  El mecanismo de autenticación es descrito en la figura que sigue:


El proceso de autenticacion tiene dos fines básicos, el primero es el control de acceso en si que  permite solo la entrada a usuarios autorizados, el segundo se desprende del primero toda vez que en base a quien entra se tomarán las desiciones acerca de que recursos estarán disponibles para cada quién. Una aclaración en este caso referida a la seguridad es que la conexión de control se establece sobre un socket plano (es decir, no usa ningun tipo de criptografia, es de hecho un Telnet) por lo menos en los clientes normales, hay implementaciones como SFTP que usan ssh para la conexion de control, pero deben tener en cuenta que en este caso los pares usuario/contraseña van a  viajar como texto plano, listos para ser recogidos por un sniffer.  A falta entonces de una protección básica lo mas recomendable es (por extraño que pueda parecer) que usen accesos anónimos, cuando menos las contraseñas quedan a salvo.

 MODOS DE TRANSMISIÓN, TIPOS DE DATOS, EL PROBLEMA CON LOS MARCADORES DE FIN DE LÍNEA.

Ftp tiene tres modos diferentes de transmision a saber: el modo stream (las traducciones al castellano de "stream" arrojan mas oscuridad que luces, mejor sigan leyendo, se va a explicar solito). En este modo los datos son enviados simplemente como un flujo continuo de bytes sin estructura. No se usan formatos de mensajes con campos de encabezados (headers en lo adelante) diferentes lo que significa que el fin de archivo es indicado cuando el dispositivo que hace el envío cierra la transmisión. Este modo es el que más se usa en implementaciones reales, es el método por defecto, el más simple, el mas eficiente (no malgasta bytes en headers). El segundo modo es el modo de bloques, y como indica el nombre el dato es dividido en bloques y encapsulado en bloques ftp individuales. Cada uno de estos bloques o "records" incluye un header de tres bytes que indica su extensión (me refiero al largo a la talla) e información acerca de los bloques enviados. Ademas incluye un algoritmo especial que controla lo que se transmite y detecta transferencias interruptas (y las reinicia en tal caso). El tercer tipo es el modo comprimido, que adiciona una técnica relativamente simple de compresión (elimina redundancias) y que a decir verdad no es muy útil dado que la compresión es algo que otras capas de la pila TCP/IP ejecutan normalmente y una compresión adicional no tiene caso. 

Bien, ahora vamos con los tipos de datos, que nos trae el primer problema interesante del protocolo. Primero, el ASCII, es decir texto (que debe incluir algun tipo de marcador de fin de línea), el segundo EBCDIC (lo usan los mainframes de IBM, al final es otro código para caracteres alfanuméricos, es decir parecido a ASCII, pero de IBM.... sip esas cosas existen :-)), el tercero son las imágenes o mejor conocidas como binarios, son archivos sin estructura interna que se mueven un byte a la vez, ¿recuerdan el modo de transmisión stream? pues a eso me refiero. El cuarto y último es el tipo local, que es usado para almacenar datos en bytes lógicos con un numero de bits diferentes de 8, permite resolver algunos detalles de compatibilidades de representaciones de datos. Bien, ¿cual de todos creen que da problemas aquí?, pues el que menos se imaginan, el texto simple (ASCII). El problema viene del hecho de que todos los sistemas no definen de igual modo los marcadores de fin de línea, así en UNIX solo se emplea el "LF" (line feed) Macintosh emplea un "CR" (carriage return), y Windows usa los dos "CR+LF" así que si tratas de transferir un texto desde un UNIX hacia un Mac o un Windows como un stream (es decir, sin cambiar nada) lo que recibirás sera un desorden que no vas a entender. Aqui ftp incorpora cierta inteligencia para salir del lío, y lo que hace simplemente es convertir los marcadores de fin de linea en el emisor (sea el que sea) al modo "neutro" CR+LF y en el receptor lo regresa al formato que le corresponda. Por ejemplo si mueves un texto desde un Mac hacia un UNIX, en cada fin de línea se cambiará "CR" por "CR+LF" y en el otro extremo (UNIX) cada CR+LF será cambiado por un LF, de modo que la aplicación en UNIX lo podrá leer apropiadamente. 


A estos tipos se adicionan  tres posibles estructuras de datos,  (FILES, RECORDS y PAGES) y tres posibles formas de control de formato (solo para  ASCII y EBCDIC) que son : "NON PRINT", "TELNET" Y "CARRIAGE CONTROL / FORTRAN". Si les diera por sacar cuentas las posibles combinaciones de todos arrojan que tendremos 72 posibles modos de transferir y almacenar un archivo pero por suerte sea porque algunos estan obsoletos o porque la mayoría de las implementaciones no lo soportan  al final solo quedan ASCII o Binarios.

Si alguna vez usaran cualquier cliente de los viejos y se descargan un ejecutable sin antes especificar "binary" (es el comando que activa el modo de transferencia binario, si quieren revisar los comandos revisen el man) es que el ejecutable ya no va a ser mas ejecutable porque lo transfirieron como ASCII asi que se desgració :-P, y hablo de los viejos porque la mayoría de los clientes actuales "saben" lo que hacen.


LOS MODOS DE CONEXIÓN, LAS CONEXIONES ACTIVAS Y LOS PUERTOS BLOQUEADOS.
Y ahora nos vamos a los dos modos de conexion del servicio, el modo pasivo y el modo activo (y los problemas que acarrea). La explicación ...  en video, luego lo comentamos:

MODO ACTIVO ¿EL PROBLEMA?



Como ven, el problema que nos presenta el modo de conexión activa es de seguridad, toda vez que el servidor es quien inicia las conexiones de datos, en algún momento el cliente deberá aceptar una conexión entrante a un puerto determinado (el 1621 en el ejemplo) que normalmente va a ser uno de los llamados puertos efímeros, y en general los clientes sospechan de ese tipo de conexiones (lo normal es que ellos mismos inicien las conexiones), así que las bloquean (también esto depende de que clase de firewall este usando el cliente, los cortafuegos de estado (stateful firewalls en inglés) no deberían tener problemas con esto). 

Adiciónenle a esto el hecho de que en cada transferencia de datos el cliente usará un puerto diferente (ftp permite que se use el mismo puerto de control del lado del cliente para transferir datos pero esto rara vez sucede, todo se complicaría aun más) dado que cada que se cierra una conexión la regla indica que el puerto no podrá ser usado durante un lapso de tiempo determinado para prevenir que dos sesiones consecutivas se mezclen (además de que  demora mas cerrar una conexion que abrirla, ambos extremos deben ponerse de acuerdo y el procedimiento en general es mas complicado de lo que pudiera parecer), asi que usar el mismo puerto para transferencias / conexiones consecutivas pondria la eficiencia del protocolo virtualmente de rodillas.

MODO PASIVO ¿LA SOLUCIÓN?


De modo que el uso de conexiones pasivas es una solución. La mayoría de los cortafuegos tienen bastante más problemas lidiando con conexiones entrantes hacia puertos raros que con conexiones salientes.  La RFC-1559 Firewall-Friendly FTP, discute este asunto en detalle. Recomienda de hecho, que los clientes usen conexiones pasivas por defecto en vez de usar conexiones normales usando el comando PORT, todo para evitar el problema de los puertos bloqueados.
Una última aclaración sobre este asunto, que el cliente use el modo pasivo no elimina el problema, sino que lo transfiere al lado del servidor :-) pero es mas fácil en general resolver este asunto del lado del servidor y al final estos deben ser capaces de aceptar transferencias pasivas de los clientes así que lo usual es que reserven un bloque de puertos para este propósito por los que aceptar conexiones entrantes.
  
Notas finales y bibliografía.
Esto es lo básico del protocolo FTP, si quieren profundizar aun más les dejo debajo un par de enlaces útiles:
  • El volumen 1 de TCP/IP Ilustrado (Los protocolos), es la guía por excelencia para toda la suite (yo tengo el impreso, me lo compró mi tía :-)). 
  • La Guia TCP/IP, el pdf es complicado de conseguir pero aquí tienen la version online. Tiene (igual que el anterior) un estatus cuasi bíblico cuando de bibliografia sobre redes y protocolos se trata. 
Ahora si, hasta aquí. Quiero hacerles la demostración de que tan vulnerable es el protocolo Telnet (ya que lo tratamos en este post), creo que para el próximo post será, así que saludos y provecho.