Si estás leyendo este artículo seguramente sea porque ya conoces Redis, un motor de base de datos basado en clave/valor que almacena los datos en memoria y que últimamente, debido al alto rendimiento que ofrece, está de moda.
En este artículo se detallarán medidas de seguridad a aplicar para asegurar su fortificación.
En la mayoría de los sistemas Linux las instalaciones por defecto ya tienen en consideración algunas de estas inquietudes, pero por requisitos o por instalaciones manuales en ocasiones son modificadas.
La propia documentación de Redis nos pone en aviso de que está diseñado pensando en los mundos de Yupi: "Redis is designed to be accessed by trusted clients inside trusted environments", algo extraño teniendo en cuenta que su autor es Salvatore Sanfilippo (antirez), al que conocemos de otros proyectos como hping
1.- Escucha del servicio.
El demonio de redis debería escuchar únicamente en loopback o un socket de Unix. Si no, nuestro servicio será accesible a toda la red, por defecto, sin autenticación.
Para configurar las interfaces en las que escucha se debe modificar el fichero redis.conf y especificar las IPs en el parámetro bind y el puerto con el parámetro port, que en caso de ser 0, no permitirá conexiones TCP.
Tal y como comentaba inicialmente, esta configuración viene por defecto para 127.0.0.1 6379/tcp pero en ocasiones "pasan cosas", tal y como se puede ver en shodan
port 6379 bind 127.0.0.1
En caso de que sea necesario el uso por red, es conveniente filtrar el puerto mediante un firewall en local.
# 6379 = redis port # 10.1.2.3 = clientIP1 iptables -I INPUT -p tcp --dport 6379 -s 10.1.2.3 -j ACCEPT iptables -I OUTPUT -p tcp --sport 6379 -d 10.1.2.3 -j ACCEPT
iptables -I INPUT -p tcp --dport 6379 -j DROP
Para habilitar el socket de unix se especifica mediante los siguientes valores.
unixsocket /var/run/redis/redis.sock unixsocketperm 755
2.- Ejecución con los mínimos privilegios.
El servicio debe arrancarse bajo un usuario no privilegiado específico y si es posible, en un entorno enjaulado. Como veremos en el siguiente artículo esto puede volverse uno de los mayores problemas.
El cambio de usuario implica que los ficheros que utiliza el motor sean también propiedad de este usuario. Como son el fichero de PID (especificado mediante pidfile en redis.conf), el log (logfile) y los directorios de la base de datos (dir).
En caso de Ubuntu todos estos parámetros de arranque están en el propio script de inicio: /etc/init.d/redis-server, al igual que en CentOS: /etc/rc.d/init.d/redis
En general, estos parámetros también deben estar así si se instala un paquete, aunque por desgracia si se desea enjaular será necesario hacerlo manualmente.
pidfile /var/run/redis/redis-server.pid logfile /var/log/redis/redis-server.log dir /var/lib/redis
3.- Establecer autenticación.
Este punto es crítico, ya que por defecto se puede acceder a la base de datos sin ningún tipo de autenticación. El acceso es total y permite ejecutar absolutamente todos los comandos de la base de datos.
Para establecer autenticación se debe especificar una contraseña (en texto claro) con el parámetro requirepass en el archivo redis.conf
Redis no soporta usuarios ni roles, por lo que aquel que conecte tendrá todo o nada.
requirepass SuperInfinitoOOoOOoOO
Si la base de datos se replica, los esclavos deben de definir esta contraseña en su configuración.
masterauth SuperInfinitoOOoOOoOO
4.- Desactivar los comandos no usados.
La base de datos soporta decenas de comandos distintos. Algunos de ellos completamente innecesarios para el funcionamiento normal de la base de datos y mucho menos, para usuarios que no deberían tener privilegios de administración (como los desarrolladores).
Para desactivar un comando se renombra a "" (nada) y dejará de ser posible su uso. También se puede renombrar a algo desconocido para que solo aquellos que lo conozcan puedan hacer uso de la llamada.
Lo ideal es identificar los comandos que son necesarios y deshabilitar el resto, son especialmente peligrosos: FLUSHDB, FLUSHALL, CONFIG, DEBUG, MIGRATE, SLAVEOF y SHUTDOWN, Este último es usado para parar el servicio por los scripts de inicio y que por lo tanto requerirá que estos se modifiquen.
La lista completa de comandos se encuentra en: http://redis.io/commands
rename-command FLUSHALL "" rename-command FLUSHDB "" rename-command DEBUG "" rename-command SHUTDOWN SHUTDOWNSECRET rename-command CONFIG "" rename-command MIGRATE "" rename-command SLAVEOF "" rename-command CLIENT "" ... otros rename-command ...
5.- Cifrado de tráfico entre cliente y servidor.
La comunicación entre cliente y servidor es en texto plano y nativamente no es posible aplicar ningún tipo de cifrado en esta conexión. Si la red no es confiable (ninguna lo es) se debe utilizar una segunda herramienta sobre la que delegarlo. Existen múltiples opciones como stunnel, socat o ssh.
# cliente stunnel -c -d 6379 -r servidor_redis:1999 # servidor stunnel -d 1999 -r localhost:6379
6.- Almacenamiento de registros.
Los ficheros de registro deben salvaguardarse en un directorio seguro. Estos archivos deben rotarse y mantener la misma política de seguridad que para otros registros del sistema. Si no se define logfile serán mandados a la salida estandar del sistema. Si el parámetro daemonize está activado, serán enviados a /dev/ null.
loglevel notice logfile /var/log/redis/redis-server.log
Si fuera necesario, existe la posibilidad de mandar los ficheros a syslog.
syslog-enabled yes syslog-ident redis syslog-facility local0
7.- Ajustes de rendimiento.
Como comentábamos inicialmente redis está diseñado pensando en el rendimiento, por ese motivo cambiar ajustes que afecten a este aspecto es un problema importante. Desgraciadamente, obtener el máximo rendimiento y ser susceptible a una denegación de servicio abusando de los recursos de memoria o red suelen ir de la mano.
Para ajustar esta línea, se debe jugar con varios parámetros que permitirán que el servicio permanezca estable y siga siendo óptimo en su rendimiento. De momento no existe una fórmula mágica para definirlos, dependerá de las especificaciones hardware de los servidores, número de peticiones y otros factores.
maxclients XXXX timeout XXX tcp-keepalive XXX maxmemory XXXXXXXXX
Referencias:
6 comments :
Gracias por la info, la verdad que me viene muy bien para mis futuros planes!! :D
El de mañana, que es de romper, es el divertido 8-)
¡Me encanta el post de hoy! Es de los de guardar :)
Y acabo de leer que el de mañana va a ser más diver :? :D
Qué manía tiene esta gente de guardar todo! Siempre tuve la esperanza de que estas cosas, en algún momento, mueriesen. Porque muera el servicio, porque decidan reutilizar almacenamiento... pero creo que estoy siendo un poco ilusa :/
s/mueriesen/muriesen
jajaja llevas razón, más seguro era XD
Gracias a tí.
Publicar un comentario