[Anterior: Rendimiento] [Contenido] [Siguiente: Shell de Usuario para la Autenticación de Pasarelas]
FTP es un protocolo que se remonta a los tiempos cuando Internet era una pequeña y amigable colección de computadoras, y todos los operadores se conocían entre ellos. En esos tiempos no existía la necesidad de filtrar o de reforzar la seguridad. Como consecuencia, FTP no se diseñó para el filtrado ni para que pasara a través de cortafuegos o para que funcionara con NAT.
Se puede usar FTP de dos modos: pasivo o activo. Generalmente, la elección entre el modo activo o el pasivo se toma para determinar quién tiene el problema con los cortafuegos. La realidad es que para mantener a los usuarios contentos será el administrador quien tenga que dar soporte para ambos modos.
Con FTP activo, cuando un usuario se conecta a un servidor de FTP remoto y requiere información o un fichero de éste, el servidor de FTP abre una nueva conexión de vuelta al cliente para transferir los datos que le ha requerido. Esto se conoce como la conexión de datos. Para empezar, el cliente de FTP escoge un puerto aleatorio por el que recibirá la conexión de datos. El cliente envía al servidor de FTP el número de puerto que ha escogido, y permanece a la espera de recibir una conexión entrante por este puerto. Entonces el servidor de FTP inicia una conexión a la dirección del cliente por el puerto elegido, y da comienzo a la transferencia de los datos. Esto supone un problema para los usuarios que intenten obtener acceso a servidores de FTP que se encuentren detrás de una pasarela de NAT. Debido al funcionamiento propio de NAT, el servidor de FTP inicia la conexión de datos conectándose a la dirección externa de la pasarela de NAT por el puerto elegido. La máquina de NAT recibe esta conexión, pero como no tiene asignación para el paquete en su tabla de estado, lo bloquea y no lo entrega al cliente.
Con el modo pasivo de FTP (el modo predeterminado con el cliente de ftp(1) de OpenBSD), el cliente envía un requerimiento al servidor para que éste escoja un puerto aleatorio en el que permanezca a la escucha en espera de la conexión de datos. El servidor informa al cliente sobre el puerto que ha escogido, y el cliente se conecta a este puerto para la transferencia de datos. Desafortunadamente, esto no es siempre posible o deseable debido a la posiblidad de que exista un cortafuegos delante del servidor de FTP bloqueando la conexión de datos entrante. En OpenBSD, ftp(1) está configurado para usar el modo pasivo de forma predeterminada; para forzar el modo activo de FTP, hay que usar el indicador -A de la orden ftp, o desactivar el modo pasivo mediante la orden passive off desde el punto de inserción de ftp>.
Como se ha indicado anteriormente, FTP no pasa muy bien a través de NAT y cortafuegos.
PF dispone de una solución para esta situación, redireccionando el tráfico de FTP a través de un servidor proxy de FTP, un proceso que actúa como «guía» para el tráfico de FTP a través de la pasarela/cortafuegos de NAT. La proxy de FTP que usan OpenBSD y PF es ftp-proxy(8). Para activarla, hay que añadir una línea parecida a la siguiente en la sección de NAT del fichero pf.conf:
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 \
port 8021
Una breve explicación de esta línea es: «El tráfico en la interfaz interna se redirecciona al servidor de proxy de esta máquina, que está a la escucha por el puerto 8021».
Para que esto funcione, es obvio que el servidor de proxy debe estar iniciado y funcionando en la máquina de OpenBSD. Para ello hay que introducir la siguiente línea en el fichero /etc/inetd.conf:
127.0.0.1:8021 stream tcp nowait root /usr/libexec/ftp-proxy \
ftp-proxy
y a continuación reiniciar el sistema o enviar una señal de 'HUP' a inetd(8). Una forma de enviar la señal de 'HUP' es mediante la orden:
kill -HUP `cat /var/run/inetd.pid`
Se podrá observar que ftp-proxy estará a la escucha en el puerto 8021, el mismo puerto al que la declaración de rdr anterior estaba enviando el tráfico de FTP. La elección del puerto 8021 es arbitraria, aunque 8021 es una buena elección ya que no está definido para ninguna otra aplicación.
Nótese que ftp-proxy(8) sirve para ayudar a los clientes de FTP que se encuentran detrás de un filtro de PF, no para manejar un servidor de FTP que se encuentre detrás de un filtro de PF.
Para este caso, PF estaría funcionando en el mismo servidor de FTP, en lugar de hacerlo en una máquina separada de cortafuegos. Cuando dé servicio a una conexión de FTP pasiva, FTP usará un puerto TCP alto, aleatorio, para los datos entrantes. ftpd(8), el servidor nativo de FTP en OpenBSD, está configurado para usar de forma predeterminada un puerto en el rango entre 49152 y 65535. Obviamente, es necesario permitir el paso para estos puertos, junto con el puerto 21 (el puerto de control de FTP):
pass in on $ext_if proto tcp from any to any port 21 keep state
pass in on $ext_if proto tcp from any to any port > 49151 \
keep state
Nótese que es posible restringir el rango de puertos de forma considerable; en el caso del programa ftpd(8) de OpenBSD, esto se hace usando las variables net.inet.ip.porthifirst y net.inet.ip.porthilast de sysctl(8).
En este caso, el cortafuegos debe redireccionar el tráfico al servidor de FTP, además de no bloquear los puertos requeridos. Para el ejemplo de esta sección, asumiremos que el servidor de FTP en cuestión es el de ftpd(8) estándar de OpenBSD usando el rango de puertos predeterminado.
He aquí un ejemplo de un subgrupo de reglas con el que se obtendría esto:
ftp_server = "10.0.3.21"
rdr on $ext_if proto tcp from any to any port 21 -> $ftp_server \
port 21
rdr on $ext_if proto tcp from any to any port 49152:65535 -> \
$ftp_server port 49152:65535
pass in quick on $ext_if proto tcp from any to $ftp_server \
port 21 keep state
pass in quick on $ext_if proto tcp from any to $ftp_server \
port > 49151 keep state
Se puede encontrar más información sobre el filtrado de OpenBSD y el funcionamiento de FTP en el siguiente documento:
[Anterior: Rendimiento] [Contenido] [Siguiente: Shell de Usuario para la Autenticación de Pasarelas]