Archivo de la etiqueta: mysql

Punto de acceso inalámbrico con autentificación a través de servidor Radius y MySQL

Si hace unos meses os mostraba cómo crear conexiones VPN entre máquinas Linux y Windows con autentificación a través de servidor Radius y MySQL hoy veremos cómo aprovechar la misma estructura para autentificar usuarios que se conecten a nuestra red wifi de manera que tengamos todo el entorno de acceso a nuestra red integrado. En capítulos posteriores puede que veamos cómo añadir más servicios.

Ante todo aviso que no soy ningún experto en la materia y puede que diga cosas que no son correctas 😛 , por favor, no dudéis en corregirme.

La parte más importante del sistema la tenemos ya preparada, si necesitas montar todo el servidor Radius puedes leer el artículo anterior donde se explica bien el procedimiento. En esta ocasión nos centraremos en hacer que el servidor Radius que ya teníamos autentifique a los usuarios que se conecten a nuestro punto de acceso inalámbrico.

En un escenario normal es el punto de acceso el que se encarga de autentificar al cliente que intenta conectarse a través de las conocidas contraseñas (técnicamente shared-keys) con el inconveniente de que todos los usuarios deben utilizar la misma y si hay que cambiarla hay que comunicar a todos ellos cual es la nueva.

Hay dos conceptos dentro de todo este sistema que van siempre juntos pero son distintos:

  1. La encriptación de la comunicación entre el cliente y el punto de acceso, las conocidas WEP, WAP y WAP2.
  2. La shared-key de acceso al router.

Estos dos elementos son completamente independientes. No me voy a meter técnicamente en los distintos tipos de encriptación ya que no son el objetivo del artículo y hay toda la documentación que quieras al respecto. Para nuestro ejemplo vamos utilizar WPA2 con cifrado AES. Recuerda que estos parámetros sólo importan al punto de acceso y al cliente que se conecta, se utiliza para asegurar el canal inalámbrico, el servidor Radius es completamente ajeno a estos mecanismos.

En nuestro escenario el procedimiento descrito anteriormente quedaría como muestra este gráfico.

Dibujo1

Es decir, para que un cliente se conecte a nuestro punto de acceso necesitará las credenciales adecuadas. Una vez el AP las recibe, consulta al servidor Radius si son correctas y debe dejarle pasar, en cuyo caso el cliente ya puede acceder a nuestra red. Cómo os habréis dado cuenta, entre el AP y Radius no he nombrado en ningún momento WAP2 o AES, éstos se utilizan sólamente en lo que en el gráfico superior es el rayo amarillo, el medio inalámbrico. En resumen, la diferencia entre la configuración habitual con shared-key estática y ésta es que permitimos que cada usuario tenga su login independiente, pudiendo cancelar su acceso en cualquier momento, algo que puede ser muy útil en ciertos ambientes, sobre todo corporativos.

Configurando el servidor Radius

Nuestro servidor Radius ya estaba configurado, sólo deberemos hacer un par de modificaciones. Primero añadimos permiso para que se conecte el punto de acceso y pueda autentificar a los clientes, para ello agregamos lo siguiente al archivo /etc/raddb/clients.conf:

client 192.168.100.100 {
	secret = clavesecreta
	shortname = osusnet
}

Donde la ip es la del APsecret es la contraseña que utilizará el AP para conectarse a Radius y shortname un identificador interno. A continuación editamos el archivo /etc/raddb/eap.conf dejando las siguientes secciones de este modo:

default_eap_type = peap

tls {
        private_key_password = whatever
        private_key_file = ${raddbdir}/certs/cert-srv.pem
        certificate_file = ${raddbdir}/certs/cert-srv.pem
        CA_file = ${raddbdir}/certs/demoCA/cacert.pem
        dh_file = ${raddbdir}/certs/dh
        random_file = ${raddbdir}/certs/random
}

peap {
        default_eap_type = mschapv2
}

Eap es el método de autenticación que se utilizará, en el caso que tratamos será PEAP (conocido también como EAP-MSCHAPv2) y necesita además TLS, por eso debemos añadir los dos en la configuración de Radius. En mi caso, la instalación de FreeRadius crea los certificados necesarios así que no entraré más en detalle sobre este tema, supondremos que existen y funcionan bien. Ya solo queda reiniciar el demonio Radius para que los cambios comiencen a estar visibles.

Configurando el punto de acceso

En este punto hemos terminado la configuración en nuestro servidor Linux. Configuraremos ahora el router, en mi caso un SMC. Tendremos que utilizar un cable ethernet para acceder al router ya que no podremos entrar por wifi hasta que lo tengamos bien configurado. La configuración en tu router será muy parecida a ésta. En las opciones “Wireless” le indicamos que la seguridad será WPA:

router4

En la configuración WPA especificamos los parámetros que hemos acordado, WPA2 y AES. Además le indicamos que no utilizaremos pre-shared key para autenticación sino que se hará a través del protocolo 802.1x. Los demás parámetros no nos importan.

router1Finalmente configuramos las opciones de autenticación 802.1x habilitándola e indicando la dirección IP de nuestro servidor Linux con Radius.

router2Ya está el router configurado. Sólo nos queda hacer lo propio con nuestro cliente inalámbrico. Como hemos escogido WAP2 supondremos que la tarjeta wireless del portátil la soporta, si no ¿por qué la has escogido? 😛 .

Configurando los clientes inalámbricos

Al buscar las redes inalámbricas disponibles en el portátil veremos la del router que hemos configurado. Por defecto no podremos acceder a ella, debemos indicarle cómo debe autenticarse, para ello vamos a “Configuración avanzada” y en la lista de redes seleccionamos la que nos ocupa y vamos a propiedades.

En la venta que se abre seleccionamos, en la pestaña “Asociación“,  los métodos de autenticación y cifrado que hemos definido:

wifi3En la pestaña “Autenticación” seleccionamos “PEAP” como tipo de EAP y vamos a “Propiedades“:

wifi1En la ventana que se abre eliminamos la selección de “Utilizar certificado cliente” y en el método de autenticación “EAP-MSCHATP v2” vamos a “Configurar”, eliminando en la ventana que se abre la opción que viene señalada por defecto.

wifi0Aceptamos todos los cambios hacia atrás y guardamos la configuración. A los pocos segundos veremos este aviso:

wifi4Parece que funciona 😛 . Pinchamos en el aviso y nos salta la venta que buscamos:

wifi5Introducimos nuestro usuario y clave de Radius y padentro!

Eso es todo, hemos conseguido el objetivo del artículo, utilizar la misma infraestructura de autentificación para el entorno inalámbrico que la que teníamos para el acceso remoto por VPN.

Usuarios de ftp virtuales con vsftpd y MySQL

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 🙂 .

Copias de seguridad de bases de datos

A través de Pensamientos Ágiles llego a un artículo donde explican una interesante manera de hacer backups de bases de datos Mysql utilizando subversion. La idea es excelente, pero me plantea una serie de dudas si se trata de bases de datos de gran tamaño. Creo que es genial para mantener la estructura de la base de datos de un proyecto y tener controlados los cambios que se realizan sobre ella, pero mantener también los datos… no acabo de verlo.

En uno de mis proyectos tengo una base cuyo dump ocupa alrededor de 1Gb. Yo, sinceramente, no veo coherente mantener semejante archivo en svn. La idea es excelente y para bases de datos “pequeñas” creo que sí es útil, habría que decidir, en todo caso, qué entendemos por “pequeñas“. Pero insisto, no lo veo para archivos grandes, y 1Gb, tengamos el criterio de grande/pequeño que tengamos, es un archivo grande.

Normalmente lo que hago para hacer los backups es sacar un dump de cada base de datos, de manera que pueda recuperar cualquiera de ellas, y comprimir el resultado con bzip2. ¿Por qué bzip2 y no gzip? Simplemente por el nivel de compresión. En su día hicimos pruebas con ámbos sistemas y bzip2 salía mejor parado. Éstos son los resultados que obtendríamos hoy en día con la compresión estándar de ámbos sistemas:

-rw-r--r--   1 osus   users  1023246033 Feb  2 01:50 bbdd.sql
-rw-r--r--   1 osus   users   141481434 Feb  2 01:50 bbdd.sql.bz2
-rw-r--r--   1 osus   users   190733372 Feb  2 01:50 bbdd.sql.gz

Con bzip2 el backup pesa unos 50mb menos.

El script que utilizo para hacer backups de base de datos es más o menos lo que suele hacer la mayoría de la gente:

#!/bin/sh
dia=`date +%w`
for i in ` /usr/bin/mysql -N --execute='show databases;' `
do
echo "Haciendo backup de $i"
/usr/bin/mysqldump -C --opt $i > /backup/bbdd/$dia/$i.sql
bzip2 -fz /backup/bbdd/$dia/$i.sql
done

En otras palabras, mantengo las copias completas de los últimos siete días, semanalmente se se reemplazan por las del día en que nos encontramos. En la carpeta del día correspondiente genero los dumps comprimidos de todas las bases de datos.

El último paso es copiar los dumps del día a otra máquina. La tarea que se ejecuta diariamente lanza el proceso una vez termina de crear los backups. Esto lo hacemos a dos máquinas distintas. La primera es una máquina externa y se envían por ssh desatendido, utilizando claves públicas, de manera que la máquina remota no solicita la clave del usuario. La segunda es una máquina de nuestra oficina con la que tenemos una vpn que se levanta antes del backup, se copia con ssh destendido también y se cierra al terminar. En ésta máquina de la oficina hay otra tarea que diariamente restaura el backup de ciertas bases de datos en su Mysql local matando así dos pájaros de un tiro: por un lado tenemos la base de datos de desarrollo casi idéntica a la de producción, faltarían sólamente los últimos datos del día, y por otro lado nos aseguramosn de que los backups que se realizan son correctos ya que en caso contrario fallaría la restauración.

Hasta ahora nos ha funcionado bien el sistema. En alguna ocasión hemos tenido que recuperar alguna tabla de ciertas bases de datos y no hemos tenido excesivos problemas, todo ha funcionado a la perfección.

Vuelvo a repetir que esto no es una crítica al sistema del subversion, todo lo contrario, la idea me parece cojonuda, pero creo que habría que puntualizar o estudiar bien la viavilidad en ciertos escenarios.

[ERROR] /usr/libexec/mysqld: Incorrect key file for table

O cómo cargarte un servidor de bases de datos por tocar un parámetro de configuracion 😛 .

Hace un par de semanas tuvimos una incidencia con el MySQL de uno de nuestros servidores. Algunas tablas comenzaron a devolver errores extraños referentes a /tmp y al archivo de índices de algunas tablas. Lo siento, no tengo el mensaje concreto. El caso es que la base de datos estaba inutilizada. Tras investigar un poco por Google comencé a probar algunos cambios de parametrización en /etc/my.cnf. Me pareció muy extraño puesto que la configuración que utilizamos lleva muchos años dando buen resultado, de hecho no es ni por asomo hoy por hoy el momento de mayor actividad que hemos tenido.

Tras hacer un poco el tonto caí en la cuenta, ríanse de mi, de que la máquina se había quedado sin espacio en disco 😛 . Era esto lo que provocaba que no se pudieran regenerar los índices de las tablas y demás errores asociados.

Una vez solucionado el error todo comenzó a funcionar con normalidad y parecía que todo iba bien. Craso error.

Hace unos días nos dimos cuenta que el log de MySQL se estaba llenando de mensajes de error como éste sin aparente explicación:

080902  0:51:42 [ERROR] /usr/libexec/mysqld: Incorrect key file for table ‘./basededatos/tabla.MYI’; try to repair it

Lanzando un repair table tabla se solucionaba el error, pero era algo temporal, pronto volvía a aparecer, sino era con esa tabla era con otras. Incluso tablas de bases de datos sin apenas uso.

Googleando de nuevo, el primer resultado me dió la clave. , era uno de los parámetros que había modificado el día que me había quedado sin espacio en disco y no lo había restaurado.

key_cache_block_size=1024

Había leído que aumentando este parámetro se solucionaría el error, así que ni corto ni perezoso lo puse a 10024 y así se quedó aunque el problema no se solucionó 😛 .

Al parecer este parámetro debe tener un valor que sea potencia 2 de 512, sino aparecerán los errores aleatorios en los archivos de índices que nos estaban ocurriendo a nosotros.

Restauramos el valor a 1024, reiniciamos el servidor de bases de datos y, por arte de magia, los problemas desaparecieron.

Como conclusión sacamos que el parámetro más absurdo puede hacernos perder días de investigación y problemas, en mi caso a las cuatro de la madrugada 😛 . Esta vez tuvimos suerte. Para la próxima, pensaré en apuntar cada cambio que haga, por si acaso…

Modelando bases de datos con MySQL Workbench

Si hay una herramienta de diseño de bases de datos conocida dentro del software libre, ésta es, sin duda, DBDesigner. Si a estas alturas no la conoces es que no diseñas bases de datos o lo haces sobre la marcha, tu sabrás lo que haces :).

Hace algunos años MySQL compró Fabforce, la empresa que desarrollaba aquél software. No he podido encontrar la fecha exacta, pero ya en agosto de 2005 se anunciaba el lanzamiento de la primera alpha de su sucesor, MySQL Workbench. Obviamente algo tiene que haber trastocado los planes iniciales de lanzamiento puesto que en abril de 2008 estamos todavía con versiones beta, eso sí, en estado ya Release Candidate. Cabe señalar que la última versión de DBDesigner es nada más y nada menos que de 2003, y aún así se sigue utilizando.

Lo interesante de este nuevo producto es que está basado completamente en su antecesor, el equipo de desarrollo es exactamente el mismo e incluso han dejado una opción para importar diseños creados con DBDesigner.

Tal como indican en el antiguo foro del programa, fabForce mantendrá el sitio web de DBDesigner hasta que se publique la primera versión de MySQL Workbench, a partir de ese momento desaparecerá. Parece que el momento está cerca.

Mi impresión es que, a pesar de los planes que tenían para el producto después de la compra por MySQL, se antepusieron productos nuevos. Nada más ni nada menos que el conjunto de nuevas utilidades bajo entorno gráfico que aparecieron hace un par de años: MySQL Administrator, QueryBrowser y Migration Toolkit, todas ellas desarrolladas por el equipo de DBDesigner, fantásticas utilidades por cierto. Recordad que hasta entonces no había ninguna herramienta visual oficial para trabajar con MySQL, las que había eran todas de terceros, una clara desventaja dentro del sector de pequeña y mediana empresa en el que pretendían entrar después del gran éxito en entornos web.

¿Qué hacía de especial a DBDesigner?

Lo primero y fundamental, una herramienta visual para modelar bases de datos y crear diagramas e/r al más puro estilo de Oracle DBDesigner o los Diagramas de SQL Server. A esto hay que añadir las increíbles funciones de sincronización e ingeniería inversa. La primera permite reflejar automáticamente en tu diseño los cambios realizados sobre tu base de datos en el servidor y viceversa, no es necesario crear toda la base de datos de nuevo. La segunda permite leer una base de datos completa desde tu servidor y crear automáticamente el esquema. Si no los has probado no sabes lo que te pierdes.

Otra de las funcionalidades era la posibilidad de crear plugins para extender sus utilidades. Traía algunos de serie, uno de ellos, SimpleWebFront, permitía generar una aplicación CRUD completa de tu diseño en PHP sin tocar una sóla línea de código.

Finalmente debemos señalar que se podía trabajar ya en aquel momento con otros gestores de bases de datos, Oracle, MSSQL, SQLLite, ODBC…

¿Qué hay de nuevo?

Han tenido que pasar cinco años para que veamos una nueva versión de una de las mejores herramientas que han existido para MySQL. Algo nuevo tiene que aportar. Básicamente se ha mantenido la esencia de la antigua aplicación modernizando la interfaz y añadiendo algunas opciones nuevas.

La mala noticia es que saldrán dos versiones, la de comunidad, gratuita, y la comercial. La diferencia fundamental es que las opciones de sincronización e ingeniería inversa contra el servidor se han dejado para la versión de pago, pero aparece una opción en la libre que permite hacer lo mismo con archivos SQL en vez de en vivo. La mayoría de nuevas funciones se incluirán en la versión comercial, pero os aseguro que no son indispensables, hablamos distintas opciones de debug y notación.

Entre los planes de MySQL figuran crear una comunidad de desarrolladores de extensiones y plugins que permitan nuevas opciones, con lo cual no sería de extrañar que la primera en aparecer fuese una versión libre de las opciones en vivo antes comentadas.

Lo mejor es que la pruebes y obtengas tu propias conclusiones. Para mi siempre es el primer paso al preparar una nueva aplicación. Si tienes un buen modelo visual es muy sencillo preparar tus clases del modelo o decirle a alguien lo que tiene que hacer sin tener que estar revisando continuamente la estructura desde el servidor.

La versión final está al caer. Mientras tanto puedes descargar la última beta desde aquí.