Bueno llevaba mucho tiempo sin publicar nada pero esta vez lo estoy viendo muy necesario, entonces quise hablar un poquito de algo que había hecho hace muchos años pero que en aquel entonces quizá no tenia los criterios técnicos para hablar bien del tema.
En este momento quiero mostrarles un servidor FTP el cual autenticara sus usuarios con unos creados previamente en bases de datos de MySql, todo esto a través de las librerías PAM.
Conceptualizando:
FTP
No quiero entrar en mucho detalle sobre el protocolo FTP por que comenzaríamos a hablar de activos y pasivos de puertos y de un montón de criterios que en realidad nos alargarían mucho la entrada, pero entonces quiero contarles que un servidor FTP es un servidor en el que intercambian archivos los clientes y el servidor todo esto para diversas funciones, una de las mas utilizadas es la administración de un servidor web, es decir, si yo tengo un servidor web en el que tengo una pagina y en ese mismo lugar tengo un servidor FTP, esto me brinda la ventaja de administrar los archivos de mi pagina web a través del FTP facilitando así la actualización de esta. (Cabe resaltar que también se usan en infinidad de procesos pero este es uno de los ejemplos mas puntuales.)
VSFTPD
Según http://www.guia-ubuntu.org vsftpd, son las siglas de "Very Secure FTP Daemon" : Demonio FTP muy seguro, es un servidor FTP. Está licenciado bajo la licencia GNU. Soporta IPv6 y SSL.
MySql
Hemos hablado muchas veces en este blog sobre MySql y solo quiero decirles que es un excelente y muy utilizado gestor de bases de datos relacionales.
PAM
Este no es un mecanismo de autenticación mas bien este proporciona una interfaz entre las
aplicaciones de usuario y diferentes métodos de autenticación.
Mediante PAM podemos comunicar a nuestra aplicaciones con los métodos de
autenticación que deseemos de una forma transparente, lo que permite
integrar las utilidades de un sistema Unix clásico (login, ftp,
telnet...) con esquemas diferentes del habitual password: claves de un
solo uso, biométricos, tarjetas inteligentes. Como por ejemplo en este caso tratar de autenticar los usuarios que ingresen al FTP no con el archivo /etc/passwd (usuarios locales) sino con MySql.
Instalando.
Les recuerdo que estamos en un sistema operativo CentOs 6 y aquí comenzaremos por instalar MySql (cliente y servidor), el soporte de PAM para MySql y finalmente el servidor FTP.
Configurando MySql.
Ahora iniciaremos la configuración de MySql (yo se que muchos ya deben tener esto listo pero les pido paciencia por que quiero mostrar paso a paso para que quienes no lo saben no se lo pierdan):
Reiniciamos el demonio de MySql.
Iniciamos una instalación segura en la que definiremos la contraseña de root y eliminaremos los usuarios anonymous.
Borramos las bases de datos de prueba, deshabilitamos el acceso remoto como usuario root y recargamos la tabla de privilegios.
Asumiendo entonces que todo nos salio bien, procedemos a ingresar al MySql.
Aquí comenzaremos la creación de las tablas y las bases de datos, además de esto insertaremos los parámetros de credenciales para los usuarios.
mysql> CREATE DATABASE vsftpd; #Esto crea una base de datos para ingresar los usuarios del ftp.
mysql> CREATE USER vsftpd; #Esto crea el usuario propietario de la base de datos del ftp.
mysql> GRANT ALL ON vsftpd.* to 'vsftpd'@'localhost' IDENTIFIED BY 'vsftpdpass'; #Aqui estamos dandole permisos a todo lo que contenga la base de datos del ftp al usuario vsftpd@localhost.
mysql> CREATE TABLE `vsftpd`.`accounts` ( `id` INT NOT NULL AUTO_INCREMENT , `username` VARCHAR( 30 ) NOT NULL , `pass` VARCHAR( 50 ) NOT NULL , PRIMARY KEY ( `id` ) ) ENGINE = MYISAM; #Bueno dentro de la base de datos creamos una tabla que se llama "accounts", la cual va a tener dentro dos campos uno que es "username" y otro que es "pass" estos son solamente los títulos, en el siguiente valor si lo podemos cambiar por nuestros usuarios.
mysql> INSERT INTO vsftpd.accounts(username,pass) values('user1',password('password1')); #En este campo estamos diciendo que dentro de la base de datos vsftpd, dentro de la tabla accounts, dentro del campo "username" ingresaremos el usuario "user1" (que es nuestro usuario de ejemplo) y dentro del campo "pass" ingresaremos "password1" que es el password del usuario de ejemplo.
mysql> FLUSH PRIVILEGES; #Actualizamos los privilegios de los usuarios y listo!
Configurando el vsftpd.
Ahora crearemos un usuario del sistema llamado vsftpd lo ingresaremos al grupo users y no le daremos shell de login, además definimos /home/vsftpd como su home.
Editaremos luego el /etc/vsftpd/vsftpd.conf
Primero hacemos un backup del original y borramos todo el contenido del que vamos a usar.
Este sera su contenido.
#Deshabilita el login anonymous
anonymous_enable=NO
#Habilita usuarios locales con permisos de escritura 755
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
log_ftp_protocol=YES
xferlog_enable=YES
connect_from_port_20=YES
#Definimos el unico usuario sin privilegios.
nopriv_user=vsftpd
chroot_local_user=YES
listen=YES
# Aquí se utiliza el módulo de autenticación para vsftpd para comprobar el nombre #de usuario y passw.
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
userlist_deny=yes
#Aquí el vsftpd permitirá a el usuario 'vsftpd' iniciar sesión en "/home/vsftpd
#/$directorio de usuario
guest_enable=YES
guest_username=vsftpd
local_root=/home/vsftpd/$USER
user_sub_token=$USER
virtual_use_local_privs=YES
#Especifica un directorio para los archivos de configuración por usuario
user_config_dir=/etc/vsftpd/vsftpd_user_conf
force_local_data_ssl=NO
force_local_logins_ssl=NO
pasv_enable=YES
pasv_min_port=44000
pasv_max_port=44100
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
nopriv_user=vsftpd
chroot_local_user=YES
listen=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
userlist_deny=yes
guest_enable=YES
guest_username=vsftpd
local_root=/home/vsftpd/$USER
user_sub_token=$USER
virtual_use_local_privs=YES
user_config_dir=/etc/vsftpd/vsftpd_user_conf
force_local_data_ssl=NO
force_local_logins_ssl=NO
pasv_enable=YES
pasv_min_port=44000
pasv_max_port=44100
Configurando PAM.
Ahora lo que debemos hacer es que el PAM busque los usuarios de MySql en
vez de los usuarios del /etc/shadow y /etc/passwd lo primero que
haremos sera realizar una copia del archivo.
Editaremos entonces el archivo /etc/pam.d/vsftpd (no sin antes sacarle una copia) y luego de tenerlo vacío comenzaremos desde cero la edición de este con los siguientes parámetros.
#%PAM-1.0
session optional pam_keyinit.so force revoke
session optional pam_keyinit.so force revoke
#Lo siguiente en una sola linea.
auth required pam_mysql.so user=vsftpd passwd=vsftpdpass host=localhost db=vsftpd table=accounts usercolumn=username passwdcolumn=pass crypt=3
auth required pam_mysql.so user=vsftpd passwd=vsftpdpass host=localhost db=vsftpd table=accounts usercolumn=username passwdcolumn=pass crypt=3
#Esto en otra linea.
account required pam_mysql.so user=vsftpd passwd=vsftpdpass
host=localhost db=vsftpd table=accounts usercolumn=username
passwdcolumn=pass crypt=3
Aquí le estamos diciendo que busque la autenticación de los usuarios a través del modulo pam_mysql.so con el usuario vsftpd (el que creamos en mysql) y el password vsftpdpass (el mismo de mysql) en el host localhost, en la base de datos vsftpd dentro de la tabla accounts en los parámetros username y pass con algoritmo crypt=3 en este caso MD5.
Personalmente en los logs me salia este error.
pam_mysql - MySQL error (Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (13))
Es problema del selinux que no permite el pam y el MySql comunicarse entre sockets, en mi caso simplemente en el archivo /selinux/enforce cambie el valor "1" por "0".
Perooo... lo que acabo de hacer anteriormente lo reconozco, es una practica totalmente novata e insegura y no es recomendable hacerla. Existe una manera mas segura de hacerlo sin des-habilitar el SELinux y es utilizando los siguientes comandos.
Primero con el comando
#getsebool -a | grep ftp
Nos listara todos los servicios de SELinux relacionados con el ftp, entre ellos los que modificaremos.
ftp_home_dir --> off
ftpd_connect_db --> off
Lo que queremos es cambiar su valor de "off" a "on" y lo logramos con setsebool de la siguiente manera.
Primero con el comando
#getsebool -a | grep ftp
Nos listara todos los servicios de SELinux relacionados con el ftp, entre ellos los que modificaremos.
ftp_home_dir --> off
ftpd_connect_db --> off
Lo que queremos es cambiar su valor de "off" a "on" y lo logramos con setsebool de la siguiente manera.
#setsebool -P ftp_home_dir 1
#setsebool -P ftpd_connect_db 1
Además de esto cabe resaltar que los logs estan en /var/log/mysqld.log, /var/log/vsftpd y /var/log/secure
Continuando con mi manual entonces les recuerdo que en el archivo de configuracion del vsftpd ingresamos un parametro llamado user_config_dir=/etc/vsftpd/vsftpd_user_conf el cual nos indica que cada usuario tendra una configuracion personalizada en dicho archivo, es decir que debemos tener un archivo alli para user1.
El archivo lo dejare basicamente con estos parametros. Pueden tenerlo como quiera, por eso es personalizable para cada uno.
Podemos ver que en el definimos su /home el cual sera /home/users/user1 entonces creemoslos y le damos permisos al usuario y lo agregamos al grupo vsftpd.users.
Se supone que aqui todo deberia estar funcionando perfecto entonces primero que todo crearemos un archivo de prueba llamado probando en el /home de user1.
Luego reiniciaremos el demonio del vsftpd con /etc/init.d/vsftpd restart.
Ahora probemos!
Como podemos ver inicie sesion con user1 y su password password1 y si listamos vemos el archivo probando.
Pues ya funciona pero para que nos quede mas claro creemos otro usuario.
Primero ingresamos a MySql y allí vamos a insertar el otro usuario llamado user2 con password password2 con el siguiente parámetro.
mysql> INSERT INTO vsftpd.accounts(username,pass) values('user2',password('password2'));
Además de eso le creamos un /home llamado user2 y le dimos permisos al usuario y lo agregamos al grupo vsftpd.users.
Por ultimo y como sabia que no lo iban a recordar vine a crear el archivo de configuración personalizado para cada usuario, en este caso se llama user2.
Observamos que tome como plantilla el mismo de user1 pero cambie el /home
Finalmente dentro de este /home cree el archivo probandousuario2 e intente conectarme con las credenciales de este usuario y adivinen...
Todo salio perfecto :D...
Espero que después de mucho tiempo sin publicar entradas tecnicas les haya gustado, ahi me disculpan si a ratos me desconecto mucho pero es que las obligaciones no dan para mas :S saludos y que tengan un Feliz Dia :D