Configurar Raspbian por primera vez en Raspberry Pi 3 con seguridad (Parte II)
En la primera parte de este artículo se vio cómo instalar y configurar una Raspberry Pi con unos consejos básicos para protegernos de accesos indebidos. Aquí se añadirán unas nociones elementales para fortificar nuestra Raspi frente a intrusos. Para aumentar la seguridad se verá cómo filtrar el tráfico con la herramienta IP Tables, cómo restringir a servicios como DHCP, OwnCloud o los accesos por SSH a IPs o redes conocidas. También algunas obviedades sobre seguridad física que pasan desapercibidas, la olvidada IPv6 que estará mejor desactivada si no se va a usar y dos aspectos que no están directamente relacionados con la seguridad pero igualmente importantes: mantenimiento y monitorización.
A continuación, un índice de todos los puntos que vamos a ver:
- Instalación de Raspbian o Noobs (Parte I)
- La primera configuración de tu Raspberry (Parte I)
- Expandir el sistema de archivos (Parte I)
- Seleccionar el idioma del teclado (Parte I)
- Cambiar la contraseña del usuario Pi (Parte I)
- Cambiar el nombre del usuario Pi (Parte I)
- Habilitar SSH para acceder desde otro equipo (Parte I)
- Deshabilitar otros accesos remotos (Parte I)
- Aumenta la seguridad
- No olvides la seguridad física
- Mantenimiento y monitorización
- Unos últimos consejos que nunca están de más
3. Aumenta la seguridad
Una vez configurados los puntos más básicos de una Raspberry debemos aplicar medidas adicionales para mejorar notablemente la seguridad de los servicios que vamos a tener. En los siguientes apartados nos centraremos en medidas enfocadas a evitar ataques, sobretodo desde internet e incluso desde la propia red LAN.
Filtra el tráfico de internet con IP Tables
IP Tables es una herramienta que actua de cortafuegos o firewall. Esta herramienta forma parte del kernel y se encarga de analizar todos los paquetes de red y filtrar todos aquellos que no cumplen nuestras condiciones. Con reglas sencillas podemos bloquear la mayoría del tráfico no deseado. No obstante, es posible complicar mucho más la configuración en base a nuestras necesidades.
Antes de empezar a aplicar reglas debemos asimilar varios conceptos previos muy sencillos:
- Hay 3 tipos de tráfico:
- INPUT o tráfico de entrada. Se encarga de todo el tráfico que llega a la Raspberry con nuestra IP como destino.
- OUTPUT o tráfico de salida. Filtra el tráfico que sale de nuestro equipo.
- FORWARD o redirección. Gestiona el tráfico que llega a nuestra Raspberry pero dichos paquetes tienen una IP destino distinta de la nuestra. Es decir, no va dirigido a nuestro dispositivo. En este caso actuaríamos como un router.
- A cada tipo de tráfico anterior se le puede aplicar una política por defecto, es decir, si el paquete no cumple ninguna regla se aplica la política por defecto. Estas mismas políticas son aplicables a reglas concretas:
- ACCEPT permite que el paquete continúe su camino.
- DROP descarta o elimina el paquete sin avisar a nadie.
- REJECT descarta o elimina el paquete y envía otro paquete a la IP de origen indicando que el paquete ha sido rechazado.
- Una regla es una condición que se aplica sobre un paquete de datos. Si se cumple la regla el paquete se acepta, descarta o rechaza.
- Las reglas de cada tipo de tráfico se comprueban en el orden en que han sido introducidas. Cuando una se cumple se para la comprobación. Es decir, si un paquete cumple dos reglas, una acepta el paquete y otra lo descarta, sólo tendrá efecto la primera regla.
A continuación, se mostrarán ejemplos explicando el funcionamiento de los comandos más útiles para tratar con las reglas así como las reglas más útiles. Por último, se muestra una configuración recomendada a aplicar en la Raspberry Pi para un escenario hipotético. Estas reglas deberán ser adaptadas según las necesidades.
Podemos ver las reglas que hay incluidas en iptables con
sudo iptables -L -n -v
Donde -L lista todas las reglas , -n muestra las direcciones IP y los puertos, y -v muestra la salida por pantalla con más detalles.
Se borran todas las reglas con la siguiente orden. Esto hace que se eliminen todas las reglas y sólo se aplican las políticas por defecto.
sudo iptables -F
¡Cuidado! Es posible que hayan reglas necesarias para otras aplicaciones. Por ejemplo, Docker usa reglas FORWARD para encaminar el tráfico de los contenedores.
Aplicar reglas por defecto. Como se veía antes, estas instrucciones indican qué hacer con los paquetes si no cumplen ninguna regla:
sudo iptables -P INPUT DROP sudo iptables -P OUTPUT ACCEPT sudo iptables -P FORWARD DROP
La elección de las políticas no ha sido al azar. Damos por hecho que recibiremos ataques externos de lo más variados, por tanto, es lógico que el tráfico de entrada se bloquee por defecto por prevención. Posteriormente añadimos las reglas convenientes para indicar qué trafico es legítimo, por ejemplo, las conexiones a nuestro servidor por el puerto 80.
El tráfico de salida es aceptado por defecto porque se asume que ese tráfico que sale de nuestra Raspberry es legítimo. Esto está fundamentado en que nuestra Raspberry sólo envía tráfico saliente si nosotros lo hemos programado así manualmente o necesita responder a una petición externa que hemos permitido en INPUT. No obstante, es posible aplicar una política más restrictiva si fuera necesario pero habrá que tener en cuenta si compensa el trabajo de controlar todo el tráfico de salida. A priori, será necesario controlar las respuestas de los servicios web que tenemos con los respectivos puertos, las actualizaciones del SO, peticiones DNS, peticiones DHCP, conexiones SSH, etc.
Por último, nuestra Raspberry no es un router así que no tiene sentido permitir que se redirija el tráfico.
Sobre el aspecto de elegir DROP o REJECT en INPUT y FORWARD está motivado porque DROP no permite saber si ha habido algún error o el tráfico ha sido bloqueado mientras que REJECT sí aporta información al atacante.
Aplicar reglas al tráfico localhost. Parece extraño pero así es, el kernel también filtra el tráfico que se envía a localhost o 127.0.0.1. Este tráfico suele ser común en algunas aplicaciones para enviar datos y se envía por una interfaz de red específica llamada loopback o lo.
Para evitar filtrar este tipo de tráfico hay que añadir la siguiente regla. Sólo se aplica al tráfico entrante porque no bloqueamos el tráfico de salida.
sudo iptables -A INPUT -i lo -j ACCEPT
-A indica que se va a añadir una regla a las que ya hay en INPUT
-i distingue la interfaz de entrada por la que debe aplicar el filtro. lo equivale a la interfaz localhost o loopback.
-j decide qué hacer con el paquete. En este caso se acepta.
Para IPv6. Todas las reglas anteriores se aplican sólo al tráfico IPv4 pero también es posible gestionar el tráfico IPv6. Sólo hay que cambiar iptables por ip6tables. En nuestro caso, como no vamos a usar IPv6, os dejo las reglas que aplicaría:
sudo ip6tables -F sudo ip6tables -F -t nat #Esta regla se explicará más adelante. sudo ip6tables -P INPUT DROP sudo ip6tables -P OUTPUT DROP sudo ip6tables -P FORWARD DROP
Más campos de opciones en iptables
-p tcp/udp para indicar a qué protocolos se debe aplicar la regla. IPTables lee la información de los paquetes IP, así que es posible saber qué tipo de protocolo se está usando en la capa de transporte.
-t [tabla] indica el tipo de tabla a la que aplicar la regla. IPTables tiene distintas tablas como nat, mangle o filter.
-F o flush cuando la intención es vaciar las tablas de reglas. Es decir, se eliminan todas las reglas y se aplica la política por defecto al tráfico IP.
-s y -d dirección IP origen (source) y de destino (destination) del paquete de red respectivamente.
-sport y -dport puerto origen y destino del paquete de red respectivamente.
-o y -i distingue la interfaz de salida del tráfico y de entrada respectivamente. Mientras que -o afecta a la interfaz de salida (out), -i lo hace con la de entrada (in).
Para obtener más información sobre el resto de parámetros, como siempre es recomendable ir a la documentación oficial. También disponible para la versión IPv6 con el comando ip6tables.
Guardar las reglas de filtrado y habilitar presistencia tras reiniciar
Igual que guardamos un documento de Word cuando queremos conservar los cambios debemos hacer lo mismo con las reglas de filtrado. Sólo se aplicarán si ejecutamos este comando:
iptables-save
No todo acaba ahí. Las reglas sólo se mantendrán mientras el equipo siga activo. En el momento en que haya un reboot o se apague el sistema se perderán las reglas aplicadas. Para evitarlo debemos instalar iptables-persistent. Este servicio se encargará de hacer que los cambios en las tablas de filtrado sean permanentes.
sudo apt-get install iptables-persistent
Ejemplo práctico: Filtrando DHCP, SSH, ping y un servidor WEB
Ya hemos visto cómo funciona IP Tables, ahora veremos un ejemplo práctico explicado paso a paso. En primer lugar, se aplican las reglas básicas para permitir el tráfico localhost y saliente. También se incluye una regla para bloquear el tráfico TCP que no se ha iniciado correctamente. Después se habilitará el tráfico para servicios como ping, DHCP o un servidor web. Por último, se explican las reglas de filtrado para limitar el acceso SSH a la red local donde tenemos la Raspberry Pi conectada. También iremos un paso más allá limitando las conexiones SSH únicamente a tu ordenador.
Habilitar el tráfico localhost y saliente
Como se comentaba antes, las siguientes reglas son esenciales. Con ellas se permite cualquier tráfico saliente. Este tipo de tráfico se puede corresponder con las actualizaciones del sistema operativo o cualquier servicio que necesite acceder a internet para obtener información.
Además, a modo ilustrativo se añade una regla de seguridad. Ésta evita que se intenten iniciar conexiones si no se sigue el protocolo TCP. Aunque no tiene por qué ser crucial, sí es una buena forma de evitar que los atacantes aprovechen bugs en servicios orientados a internet.
# Todo trafico localhost permitido iptables -A INPUT -i lo -j ACCEPT # Todo trafico relacionado con conexiones activas permitido iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Eliminar cualquier paquete TCP que no se ha iniciado con el Flag SYN activo iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
Permitir tráfico selectivamente a servicios
A partir de aquí se empieza a controlar qué trafico entrante se va a permitir. Para ello vamos a asumir la siguiente configuración:
Red LAN: 192.168.1.0/24
IP Raspberry Pi: 192.168.1.100
IP router LAN y servidor DHCP: 192.168.1.1
Para aplicar las reglas de filtrado es muy importante conocer bien cómo funcionan los servicios queremos permitir. En este caso se habilitarán los servicios ping, DHCP y un servidor web en nuestra raspbian.
- Ping requests desde cualquier lugar para comprobar que el servidor sigue conectado a la red. Esto se hace con el protocolo ICMP y sólo nos interesa permitir los mensajes de tipo Echo request.
- DHCP. El servicio se comunica con el protocolo de transporte udp y a través de los puertos 67 y 68.
- Servidor WEB. OwnCloud sería un ejemplo perfecto para este caso. Asumimos que el servicio funciona sobre tcp y estará abierto en el puerto 80.
# Permitir Ping request. # Esto es algo opcional pero puede venir bien para comprobar que la Raspberry sigue activa.. iptables -A INPUT -d 192.168.1.100 -p icmp --icmp-type echo-request -j ACCEPT # Permitir mensajes DHCP para la asignación de IPs iptables -A INPUT -i eth1 -p udp --dport 67:68 --sport 67:68 -d 192.168.1.100 -s 192.168.1.1 -j ACCEPT # Permitir Owncloud u otro servidor web en el puerto 80. iptables -A INPUT -i eth1 -p tcp --dport 80 -d 192.168.1.100 -j ACCEPT
En todas podemos ver que el factor común es la IP de destino. Es importante incluir nuestra IP como dirección de destino ya que si el paquete no es para el propio equipo no debería ser tratado. Además se incluye en cada caso el protocolo de transporte utilizado y los puertos asociados al servicio.
Limitando SSH a la red LAN
Si has llegado hasta aquí ya sabrás que SSH es un programa que permite a los usuarios acceder un equipo de forma remota a través de una terminal de comandos desde otro PC, ya sea en la misma red local o desde internet. Esto permite tener un control total del equipo, por lo tanto no queremos que cualquiera pueda intentar acceder.
# Permitir SSH entrante. Sólo aceptado desde la red local 192.168.1.XXX con máscara 255.255.255.0 iptables -A INPUT -i eth1 -p tcp --dport 22 -s 192.168.1.0/24 -d 192.168.1.100 -m state --state NEW,ESTABLISHED -j ACCEPT
Siguiente nivel: Limitar SSH a la IP del propio equipo
La modificación es realmente sencilla. Sólo hay que cambiar la dirección de origen sobre la regla anterior. La IP del ordenador remoto que se conectará por SSH elegida es 192.168.1.200. En el ejemplo puedes ver la comparación:
¡Atención! Ten en cuenta que si estás conectado por SSH y aplicas la regla para una IP distinta tu conexión se bloqueará. Además, si la regla SSH del apartado anterior está incluida deberás eliminarla para que ésta tenga efecto.
# Permitir SSH entrante. Sólo aceptado desde la red local 192.168.1.200 iptables -A INPUT -i eth1 -p tcp --dport 22 -s 192.168.1.200 -d 192.168.1.100 -m state --state NEW,ESTABLISHED -j ACCEPT<strong></strong>
Esta medida está bien para poner las cosas difíciles pero no es una solución definitiva. Un atacante dentro de tu red local puede aprovechar que tu equipo no está conectado para utilizar tu IP o usar la MAC de tu interfaz de red para que le sea asignada la misma IP que correspondería a tu ordenador.
No olvides guardar para aplicar las reglas
Recuerda usar el comando iptables-save para que se apliquen las reglas.
Ahora que sabes cómo aplicar las reglas de filtrado puedes probar a adaptarlas a tu caso. Si tienes dudas sobre cómo aplicar las reglas no dudes en preguntar en los comentarios.
Si no usas IPv6, mejor desactivado
Es irónico recomendar que se desactive IPv6 cuando debería ser un avance. Sin embargo, a pesar de que se habla mucho de que viene IPv6 (también se habla mucho del blog :D ) aún no hay un uso extendido en los usuarios finales. Por lo tanto, no es necesario tener activada esta opción ni controlar los ataques con el protocolo IPv6 si no se le va a dar uso. Por supuesto, a medida que IPv6 se extienda, esta recomendación quedará obsoleta.
Hay dos opciones posibles. Una de ellas consiste en bloquear todo tráfico por IPv6 con reglas de filtrado visto en el apartado de IP Tables.
La otra opción es tan sencilla como desactivar el módulo de IPv6 del kernel modificando el fichero /etc/default/grub. Hay que modificar la línea GRUB_CMDLINE_LINUX=»» y añadir entre las comillas ipv6.disable=1 para desactivarlo. Después se ejecuta el siguiente comando y se reinicia:
sudo update-grub
Ya sea por precaución o cualquier otro motivo, es posible aplicar ambas opciones sin que entren en conflicto.
4. No olvides la seguridad física
No todos los ataques vienen por Internet o a través de la red así que este artículo no estaría completo si no contemplamos esta parte. Cuando la Raspberry Pi está en tu propia casa o un entorno confiable esto no es tan importante, sin embargo, cuando vives en un piso compartido o alguien que no debería puede tener acceso a ella puede llegar a ser un problema. Por tanto, hay que tener en cuenta la medida de seguridad más evidente:
Cuidado con quién tiene acceso a tu Raspberry Pi
Parece una cuestión obvia, lo sé, sin embargo, no por eso debe ser un aspecto menor. Además, no sólo nos debemos proteger de las malas intenciones. No sería la primera vez que alguien limpiando te ha desenchufado el ordenador mientras bajabas varios gigas de datos y al llegar a casa te encuentras con el follón. Lo mismo ocurre si necesitas que los servicios de la máquina estén disponibles las 24 horas, perder la conexión puede ser fatal según la criticidad de los archivos o servicios contenidos.
5. Mantenimiento y monitorización
Aunque no se va a entrar en detalle en este artículo, hay formas de controlar que todo funciona como debería. Una forma de hacerlo es con SNMP (Simple Network Management Protocol), un protocolo de administración de red que se encarga de comprobar, entre otras cosas, que las interfaces de red funcionan adecuadamente. Así, si la raspberry se queda sin internet o falla, una alerta nos avisará.
También es posible comprobar el uso que se hace de la red con DarkStat. Desde el navegador web se pueden ver unos gráficos con el histórico del uso de la red. Viene bien para saber quién hace uso de la red (qué IP) y cuánto uso está haciendo de ella.
6. Unos últimos consejos que nunca están de más
Muchos de las medidas que has leído aquí pueden parecer absurdas o de una lógica elemental. Sin embargo, los descuidos y la dejadez de los administradores de equipos suele ser la principal brecha de seguridad.
Aquí mi consejo favorito y probablemente el más absurdo:
¡NO OLVIDES LAS ACTUALIZACIONES DE SEGURIDAD!
Ejecuta los siguientes comandos, al menos, una vez a la semana:
sudo apt-get -y update sudo apt-get -y upgrade
El comando apt-get sirve para la instalación y actualización de programas en Raspbian. La primera línea actualiza todos los repositorios y la segunda descarga e instala todas las actualizaciones disponibles. El parámetro -y sirve para confirmar que estamos seguros de la instalación sin preguntar al usuario.
Y si eres tan perezoso como yo, inserta estas dos órdenes en tu CRON dentro del editor que aparece al ejecutar el comando sudo crontab -e y despreocúpate:
0 3 * * sun pi apt-get -y update 10 3 * * sun pi apt-get -y upgrade
La primera orden se ejecuta a las 3:00 de la mañana todos los domingos con el usuario Pi. La segunda lo hace a las 3:10 de la mañana, tiempo más que suficiente para que la primera instrucción haya acabado.
Adicionalmente, puedes ejecutar la siguiente instrucción para actualizar la versión del kernel. Hay que tener en cuenta que será necesario reiniciar la Raspberry Pi para que los cambios surtan efecto:
sudo rpi-update
Hasta aquí unos consejos básicos para mantener tu Raspberry Pi mejor preparada ante ataques de seguridad. ¿Usas otras medidas de seguridad que podrían ser útiles? Comenta más abajo qué medidas utilizas para hacer tu equipo más seguro.
Estudiante de Ingeniería Informática en la Universidad de Murcia. Enfocando mis conocimientos al mundo de las redes e Internet of Things.
Siempre informado del mundo del desarollo web, social media y marketing digital.
Gracias Eduardo.
Un buen manual con unas explicaciones claras y muy completas, es de los mejores que he visto sobre Raspberry PI en la Web, de la configuración de IP Tables decirte que me ha ayudado mucho para al menos darle algo de seguridad a la Raspberry.
Darte mi Enhorabuena por ésta Web y el contenido de la misma.
Gracias.
Atentamente. Tomás.
Buenas Días.
Soy Tomás.
Eduardo decirte algo que me pasa y no se si es que en alguna regla de iptables no deja instalarse iptables-persistent, porque al instalar de nuevo raspbian e instalar pihole y luego configurar iptables, después de actualizar con update, upgrade, aoutoremove, y clean, me da error al instalar iptables-persistent, si lo hago sin ninguna regla de iptables se instala sin problemas.
Entonces la pregunta es ¿Como no puedo instalar iptables-persistent con las reglas que comentas en la web, y si no las instalo si puedo instalar iptables-persistent? Alguna Solución?.
Gracias de antemano.
Un saludo.