Un problema que se me ha presentado más de una vez es dar acceso FTP a determinadas carpetas a usuarios que necesitan actualizar archivos en ellas. Por regla general habría que crear un usuario del sistema que tuviese su “home” en esa carpeta o un enlace simbólico desde otra, pero nunca me ha gustado la idea de crear usuarios a diestro y siniestro, aunque sean sin privilegios. Buscando un día, empecé a encontrar información sobre cómo crear usuarios “virtuales” en vsftpd y me gustó mucho la idea, combinando esto con la gestión de usuarios en MySQL podría tener un sistema bastante sencillo de dar acceso FTP a unos cuantos usuarios sin incrementar los del sistema y, por tanto, sin abrir agujeros de seguridad.
Lo primero será instalar los módulos necesarios, asumiendo que ya tienes el servidor MySQL funcionando. Nos hará falta el paquete vsftpd y el pam_mysql que permitirá hacer autentificaciones contra una base de datos de este tipo.
yum install pam_mysql vsftpd
Ahora configuramos el archivo /etc/pam.d/vsftpd para que quede así;
[osus@servidor vsftpd]# cat /etc/pam.d/vsftpd auth required /lib/security/pam_mysql.so user=vsftpd passwd=clave host=localhost db=basedatos table=usuarios usercolumn=usuario passwdcolumn=pass crypt=0 account required /lib/security/pam_mysql.so user=vsftpd passwd=clave host=localhost db=basedatos table=usuarios usercolumn=usuario passwdcolumn=pass crypt=0 session required /lib/security/pam_mysql.so user=vsftpd passwd=clave host=localhost db=basedatos table=usuarios usercolumn=usuario passwdcolumn=pass crypt=0
Esto indica a vsftpd que debe autenticarse contra “basedatos” en “localhost” con el usuario “vsftpd” y la clave “clave” y que debe buscar en la tabla “usuarios” con las columnas “usuario” y “pass“. Qué evidente es todo 😛 .
El último parámetro, “crypt“, indica el modo en que se guardarán las claves:
- 0 para claves en texto plano sin encriptar
- 1 para claves encriptadas con la función crypt()
- 2 para claves generadas con la función PASSWORD() de MySQL
- 3 para claves en md5
Escoge el sistema que prefieras. Dejaremos ahora el archivo de configuración principal de este modo:
[osus@servidor vsftpd]# cat /etc/vsftpd/vsftpd.conf ftpd_banner= "Servidor FTP" anonymous_enable=NO chroot_local_user=YES guest_enable=YES guest_username=ftpoculto hide_ids=YES listen=yes listen_address=192.168.3.254 listen_port=21 local_enable=YES max_clients=100 max_per_ip=5 pam_service_name=vsftpd use_localtime=YES user_config_dir=/etc/vsftpd/usuarios userlist_enable=YES userlist_file=/etc/vsftpd/denied_users virtual_use_local_privs=YES xferlog_enable=YES async_abor_enable=YES connect_from_port_20=YES dirlist_enable=NO download_enable=NO local_umask=000
Con esto le estamos diciendo que no permitiremos el acceso anónimo y que el usuario real que se utilizará será “ftpoculto“, los usuarios virtuales se comportarán como este usuario. Le indicamos, además, que busque los usuarios virtuales en /etc/vsftpd/usuarios y que no deje entrar a ningún usuario real, sólo a los virtuales. Para esto último haremos lo siguiente:
cat /etc/passwd | cut -d ":" -f 1 | sort > /etc/vsftpd/denied_users
Así añadimos a la lista de usuarios denegados a todos los usuarios del sistema, no hay que ponerlos a mano uno a uno 🙂 .
Ahora debemos configurar el acceso para cada usuario dentro de la carpeta “usuarios“. El nombre del archivo debe ser el mismo que el del usuario que se ha añadido a la base de datos, el que utilizará el cliente para conectarse. Yo, por ejemplo, suelo utilizar como nombres el dominio del cliente, así se quién es quién.
[osus@servidor usuarios]# cat tudominio.com dirlist_enable=YES download_enable=YES local_root=/var/www/tudominio.com/ write_enable=YES anon_world_readable_only=NO
Tendremos que configurar el directorio de este usuario para que pueda escribir en él. Para conseguirlo recordamos que vsftpd utilizaría el usuario real “ftpoculto“. Debemos, por tanto, dar permisos sobre los directorios de los usuarios virtuales a ese usuario:
chown -R ftpoculto.users /var/www/tudominio.com
Con esto, el usuario “tudominio.com” podrá moverse en /var/www/tudominio.com a sus anchas 🙂 .
La verdad es que me ha funcionado muy bien siempre. Si se combina con un sistema de acceso VPN sencillo, de manera que el puerto FTP no tenga que estar abierto púclibamente, queda todo muy robusto y seguro además de que es muy sencillo añadir nuevos usuarios, incluso lo puedes automatizar con un script ya que solamente hay que añadir un registro en la base de datos y crear el archivo de configuración en /etc/vsftpd/usuarios.
Es una buena idea en pequeños entornos ISP no dedicados o especializados, entornos donde los usuarios no van a necesitar habitualmente acceso FTP (cms, blogs, webs corporativas…).
Hay muchos más parámetros en vsftpd, desde limitar el ancho de banda por usuario hasta utilizar SSL en las conexiones, sólo hay que leer un poco la documentación 🙂 .
Enhorabuena por el post. No lograba logearme y la clave la en encontrado en tu blog, cuando te refieres al parámetro crypt.
Saludos.
Hey…. que buena información la que has publicado. He logrado tomar algunos apuntes tuyos para la configuración de mi servicio ftp.
Bye!!
la info me es util
quiza puedes ayudarme con esto
necesito dar acceso a ftp con x cantdad de espacio
como se configura esto, a modo de poder dar solamente cierto espacio de almacenamiento al usuario
El paquete de PAM MYSQL no es “pam_mysql” sino “libpam-mysql”.
Sería… “apt-get install libpam-mysql”
Hola Victor,
Debe ser entonces libpam-mysql en sistemas debian, en mi CentOs es pam_mysql, acabo de comprobarlo de nuevo por si acaso 🙂
Gracias por el aviso de todos modos.
hola !!
empleando la configuracion que posteaste si logro logearme pero usando el parametro crypt=0
el punto es que kiero encriptar la contraseña y por tanto en Mysql hago uso de la funcion PASSWORD
con esto hago un cambio en el parametro crypt=2
y asi no logro logearme
puedes ayudarme ???
Hola Gladys,
De la documentación pam_mysql (http://pam-mysql.sourceforge.net/Documentation/package-readme.php?seemore=y):
2 (or “mysql”) = Use MySQL PASSWORD() function. It is possible that the encryption function used by pam-mysql is different from that of the MySQL server, as pam-mysql uses the function defined in MySQL’s C-client API instead of using PASSWORD() SQL function in the query.
Puede que sea ese tu problema.
que tal Osus, si ya habia visto esa parte no soy muy buena en la interpretacion, el cambio que hice es este en Mysql ya no hago uso de la funcion PASSWORD ahora inserto un usuario y para la contraseña uso la funcion encrypt().
y el parametro crypt=1
asi si logro logearme, lo importante es tener la contraseña encriptada o tu q dices.
Perfecto Gladys, sin duda la solución más adecuada 🙂 .
Osus… me preguntaba si los usuarios pueden ser mas configurables con directorios especificos.
Ya todo me funciona bien, pero me gustaría tener el siguiente ambiente:
Un directorio general al cual tengan acceso todos los usuarios. Dentro de ese directorio tener varias carpetas, las cuales podrían variar los permisos según el usuario que se conecte.
No he dado con una solución.
Te agradecería si me puedes ayudar con esto.
Mil gracias
Buenas huesos52,
Yo creo que tal como lo planteas no va a ser posible, a nivel sistema de ficheros todos los usuarios virtuales utilizan el mismo usuario real con lo que no habrá control de permisos.
Lo único que se me ocurre es que utilices enlaces simbólicos a las carpetas en cuestión desde la raíz de cada usuario y les crees a cada uno los enlaces a las carpetas que quieras que puedan acceder.
Muchas gracias osus por tu rapida y eficiente respuesta…
Buscaré información acerca de enlaces simbolicos.
Un saludo
Me ha ido de maravilla con los enlaces simbolicos.
Nuevamente mil gracias Osus. Excelente blog
Como puedo especificar el usuario: (ftpoculto) para que no me salga el siguiente error —>
WinSock 2.0 — OpenSSL 0.9.8b 04 May 2006
[R] Conectando a dns2.l2spain.com -> DNS=dns2.l2spain.com IP=178.63.55.19 PORT=21
[R] Conectado a dns2.l2spain.com
[R] 500 OOPS: vsftpd: cannot locate user specified in ‘guest_username’:ftpoculto
[R] Conexión fallida
[R] Esperando 120 segundos antes de volver a intentar la conexión
Saludos y gracias
@GaDeRaTuX
He encontrado esto, a ver si te sirve:
When you connect with your client and get the following error; 500 OOPS: cannot “locate user entry:vsftpd”, look at your $user_config_dir. This error is caused when your $user_config_dir/($user) is empty.
esque no sé el que hago mal que no me conecta a el servidor FTP, es como si me equibocara de usuario/password y estoy seguro de que en MySQL esta bien especificado y en las config todo correcto
[R] Conectando a dns2.l2spain.com -> DNS=dns2.l2spain.com IP=178.63.55.19 PORT=21
[R] Conectado a dns2.l2spain.com
[R] 220 Welcome to blah FTP service.
[R] USER anonymous
[R] 331 Please specify the password.
[R] PASS (hidden)
[R] 530 Login incorrect.
[R] Conexión fallida
Eso es lo que me pasa, Que puede pasar?
hola oyes una pregunta no lo has probado para solaris 10 es que ami me interesa pero para solaris 10…
ojala y contestes…
saludos…..
@ulises,
Lo siento, no lo he probado en solaris, solo en Linux, pero debería funcionar igual 😛