Permitir FTP pasivo con iptables
Cada vez que me siento para escribir un artículo, y me gustaría hacerlo con mayor asiduidad, me doy cuenta que es para escribir sobre mi experiencia ante un problema muy concreto que me he encontrado. Al fin y al cabo, esa es la finalidad con la que empecé a escribir este blog: compartir con otra gente la solución que he encontrado ante un problema técnico.
En este caso, más que un problema simplemente se trata de desconocimiento. Mi conocimiento de iptables (el firewall de Linux, por describirlo rápidamente) es bastante limitado y se reduce a las opciones básicas: permitir y bloquear puertos, acciones de las CHAINS por defecto y poca cosa más. Pero como somos buenos técnicos, no tenemos inconveniente en leernos el manual y aprender a usar nuevas tecnologías 😀
La cuestión es que tenía una máquina Linux hospedada en un ISP conectada directamente a Internet. Con iptables, tenía configurados los puertos que permitía su administración en remoto desde una serie de ip’s de origen, y tenía abierto los puertos de los servicios que se ofrecen. Necesitaba abrir el servicio de FTP, que como muchos sabéis funciona sobre dos conexiones simultáneas: la conexión de control (que se establece por el puerto TCP/21) y la conexión de datos que puede ir por diferentes puertos, según el modo de funcionamiento del servidor: Activo y Pasivo.
La diferencia entre el modo del servidor es la siguiente:
- Para el modo ACTIVO, el cliente establece la conexión de control por el puerto TCP/21 y le envía el comando “PORT seguido por un número de puerto”. Entonces el servidor establece una nueva conexión desde el puerto TCP/20 hacia el cliente al puerto indicado. Para que este modo funcione, el cliente tiene que poder recibir la conexión procedente del servidor FTP y esto suele ser bastante inseguro. En la siguiente imagen extraída de la WikiPedia, puede verse la secuencia de conexiones.
- Para el modo PASIVO, el cliente envía el comando PASV por la conexión de control. El servidor le responde con una IP y Puerto al que debe conectarse el cliente. A diferencia del Activo, en modo pasivo, el cliente es el que establece la conexión de datos a un puerto aleatorio del servidor que le ha indicado por la conexión de control. Este es el modo más utilizado, pues normalmente entre el cliente y el servidor suele haber firewalls y routers que impiden la conexión entrante desde el Servidor de FTP, sin embargo todo el tráfico saliente está permitido. En la siguiente imagen se muestra el diagrama de conexiones.
Como puede deducirse de lo dicho anteriormente, si tenemos un firewall en el servidor ¿Qué puertos tengo que abrir para permitir la conexión de datos en un modo Pasivo, si el puerto es dinámico ?
Bueno, cabe decir antes de dar la solución con IPTABLES, que la gran mayoría de servidores de FTP permiten configurar el rango de puertos a usar, con lo que podemos limitarlos a un rango conocido y abrir esos puertos en el firewall. Sin embargo, es más elegante con la solución que os propongo.
IPTABLES tiene un módulo llamado Connection Track FTP que permite inspeccionar la conexión de control y buscar el comando PASV para ver que puerto se va a usar y abrirlo, ya que se entiende que forma parte de la misma conexión que está establecida por el puerto 21. Una vez finalizado, ese puerto se cierra nuevamente. Del mismo modo que el servidor FTP selecciona un puerto, el IPTABLES lo abre y cierra al iniciar y acabar la conexión. Con este módulo cargado, sólo será necesario abrir el puerto TCP/21.
Para cargar el módulo, ejecutaremos el comando:
/sbin/modprobe/modprobe ip_conntrack_ftp
Como no es persistente al reinicio, si quieremos tener siempre cargado el módulo cuando arranque el servidor, hay que poner el comando anterior en el fichero /etc/rc.local.
Y de esta forma, gracias al módulo Connection Track FTP podemos abrir el puerto dinámico de un FTP Pasivo con iptables de forma segura.
Una solución elegante para un problema recurrente.
Como dirían por ahí… RTFM 🙂