Armando una red doméstica nivel enterprise

Mi caminar por las redes WiFi empezó con el Linksys WRT54G hace ya varios años atrás, en ese entonces estaban de moda estos «routers» inalámbricos que hacían la función de varios dispositivos simultáneamente. Un día me tocó como estudiante en la facultad de medicina, configurar uno de estos aparatos para que su señal cubriera el edificio donde está la biblioteca y que permitiera la conexión de otros estudiantes, miembros del CIMTe (Club de Informática Médica y Telemedicina).

Lo primero que hicimos fue cambiar las antenas por otras de mayor ganancia. El resultado fue que había cobertura en el edificio, parte de los salones de estudio, en el parque Finlay y aún se lograba cierta recepción en el salón de anatomía (mala de hecho).

Luego, decidimos abrir el compás y permitir que el resto de los compañeros se conectarán a la red, previo registro para garantizar el acceso democrático para todos. Aquí fue donde comenzaron a fallar las cosas. La capacidad que tenía de manera innata este legendario aparato se quedaba corta, o mejor dicho su firmware de fábrica nos limitaba. Así que explorando opciones llegamos a la conclusión de instalar DD-WRT en ese aparato. Todo fue de maravillas y hacíamos el filtrado de los clientes por una lista por mac address de su dispositivo. Llegó incluso a recordar que desarrollé una mini webapp dentro del pobre dispositivo desde donde ingresabamos los datos de quién nos solicitaba el acceso alimentando así la lista para el filtrado por mac address e incluso pensamos expandir la red con varios access point por toda la facultad de medicina.

Durante el proceso, varios dispositivos murieron y quedaron brickeados para siempre. Luego vino la Universidad de Panamá y nos instalo un sistema llamado UP WiFi que daba internet en todo el campus y nuestro sistema perdió relevancia. Sin embargo, la experiencia de ese entonces me hizo instalarle a cada dispositivo WiFi que adquiriera después de eso una distro, ya fuera Open-WRT o DD-WRT. Con el tiempo vino el aumento de la velocidad de internet de los proveedores y se comenzó a hacer obvio un problema que no había notado antes, el rendimiento de la red comenzaba a afectarse y se obtenían velocidades no tan buenas o costaba descargar o abrir ciertos sitios web, incluso Netflix tardaba a veces en cargar los flujos de streaming.

Este problema tiene su raíz en dos cosas, el mismo «router inalámbrico» y las redes inalámbricas vecinas. Coloco entre comillas router inalámbrico porque en realidad se trata de un aparato que cumple 3 funciones que en redes de verdad es realizada por 3 dispositivos diferentes: el router, el switch y el access point. Básicamente estos enlatados son 3 dispositivos en 1, pero no sé logran desempeñar haciendo bien las 3 funciones, es por esto que hay tantas fallas o lentitud en las redes.

El otro problema es la presencia de redes vecinas. Imagina que todos tus vecinos tengan sus bocinas funcionando a todo volumen, ¿qué tendríamos? Un caos auditivo, donde no se entendería nada. Lo mismo pasa con las redes WiFi, al existir muchas, nuestros dispositivos no «escuchan» bien a la nuestra y por consiguiente no se pueden comunicar con el punto de acceso y luego vienen las páginas que no cargan o demoran en cargar. Así que cuando me mudé a mi casa deje de usar estos aparatos todo en uno y decidí armar una red doméstica de nivel entreprise.

Lo que hice fue irme por una marca ampliamente utilizada en el mundo enterprise, Ubiquiti. Si bien, la inversión no es barata, la estabilidad que gané con ella creo justifica lo que invertí en ella. Entre el arsenal de dispositivos de mi hogar hay 15 dispositivos inalámbricos y al menos 8 que requieren conexión cableada.

El reto es el siguiente, lograr cobertura Wifi excelente en toda la casa, usando el mismo SSID. Es decir, no tener varias redes que digan COCINA, SALA, DORMITORIO… etc. Ni tampoco separarlas en 2.4 GHz / 5 GHz.

Adquirí el siguiente equipo para este cometido: 1 Unifi Security Gateway (USG), 1 Ubiquiti EdgeSwitch 5XP POE (ES-5XP), 1 Unifi Access Point AC Long Range (UAP-AC-LR), 1 Unifi Cloud Key (UC-CK).

La configuración base es la siguiente: el módem está conectado al puerto WAN del USG, del puerto LAN 1 se conecta el ES-5XP y del último puerto de este se conecta el UAP-AC-LR. En esta configuración el switch como es POE alimenta el UAP-AC-LR. Cabe destacar que con esta configuración tengo cobertura hasta el parque cerca de mi casa que está a unos 100 m de distancia. Gracias a un colega, que va a realizar una implementación similar en su casa, tengo en préstamo 3 UAP-AC-LR y con esto haré las pruebas.

La gestión de casi todos los equipos se puede hacer con el UC-CK que está conectado a uno de los puertos del ES-5XP, excepto del mismo switch que no pertenece a la línea Unifi. Desde este último podemos controlar vlans y activar la función PoE de un puerto en particular.

Hasta aquí esta primera entrada sobre el tema. En la siguiente explorare varias maneras de realizar el reto propuesto y evaluaré cual de estas tiene mejor desempeño para los dispositivos.

SFTP con jaula chroot

Este es un tema que siempre me ha costado trabajo configurar, básicamente por problemas de permisos de directorios y usuarios. Luego de muchos intentos y horas de investigación lo más cercano era que los usuarios ingresaran a un directorio común desde donde podían escribir en sus directorios, pero podían ver todo el contenido de los otros usuarios.

Ante el problema anterior finalmente di con la manera de configurar una jaula chroot que contiene los archivos de un sitio web, para usuarios SFTP. El dilema a resolver es el siguiente: tenemos una instalación de nginx con varios sitios web. Crearemos un usuario sin acceso a shell que se pueda conectar vía SFTP para editar el mismo directorio desde donde se sirven los archivos.

Crear un grupo para los usuarios SFTP

Como nginx trabaja por defecto con el grupo www-data, usaremos este mismo. Opcionalmente si queremos crear un grupo exclusivo para estos menesteres.

$ sudo groupadd solosftp

Pero debemos ajustar la configuración de nginx para que utilice este nuevo grupo.

Añadir usuarios al grupo SFTP

Lo siguiente es crear y añadir el usuario que vamos a utilizar al grupo www-data o el que hemos creado en el paso previo. Antes de esto, el árbol de directorio que uso para guardar los sitios web es el siguiente: /var/www/sitio.web/public_html.

$ sudo useradd -g www-data -s /bin/false -m -d /var/www/sitio.web usuariosftp
  • -g www-data añade al grupo www-data el usuario que estamos creando.
  • -s /bin/false elimina el acceso vía shell, el usuario no podrá conectarse vía SSH.
  • -m -d /var/www/sitio.web crea el directorio del usuario

En mi caso prefiero utilizar llaves ssh para los usuarios regulares del servidor y contraseñas de texto a los usuarios SFTP.

$ sudo passwd usuariosftp

Lo siguiente es el paso más crítico, que corresponde a los permisos. Anteriormente los asignaba de manera incorrecta en el árbol de directorios. Con un error aquí puedes evitar que el usuario no ingrese o que el servidor rechace la conexión. El directorio home del usuario debe pertenecer al usuario root y tener permisos 755.

$ sudo chown root: /var/www/sitio.web
$ sudo chmod 755 /var/www/sitio.web

Ahora podemos crear los directorios que usaremos dentro de la carpeta, asignar los permisos y la propiedad y grupo que necesitamos.

$ sudo mkdir /var/www/sitio.web/{public_html,uploads}
$ sudo chmod 755 /var/www/sitio.web/{public_html,uploads}
$ sudo chown usuariosftp:www-data /var/www/sitio.web/{public_html,uploads}

Con esto hay que tener en cuenta que al crear el archivo de configuración del sitio web de nginx, la raíz apunte al directorio que hemos creado public_html.

Configurando SSH

Ahora editaremos el archivo de configuración de SSH /etc/ssh/sshd_config, editando la línea Subsystem sftp y añadiendo el bloque Match Group

Subsystem sftp internal-sftp

Match Group www-data
  ChrootDirectory %h
  ForceCommand internal-sftp
  AllowTcpForwarding no
  X11Forwarding no

Una vez hecho estos cambios reiniciamos el servidor SSH.

$ sudo systemctl restart ssh

Probando

Ahora que hemos terminado de configurar la jaula chroot podemos probar la conexión. En el mismo servidor podemos hacerlo como se detalla o bien si nos conectamos remotamente, reemplazamos localhost por la ip del servidor.

$ sftp usuariosftp@localhost

Una vez inicie el proceso, el servidor nos preguntara la contraseña de la cuenta sftp y luego podremos utilizar los comandos pwd y ls para verificar el directorio de trabajo y listar los archivos y directorios.

usuariosftp@localhost's password:
Connected to usuariosftp@localhost.
sftp> pwd
Remote working directory: /
sftp> ls
public_html  upload
sftp>

Y hasta aquí termina esta guía que espero sea de ayuda para quienquiera se aventure a hacer esto. El resultado, varios sitios web en un solo servidor con nginx y a los cuales cada uno se puede acceder vía sftp de manera exclusiva sin que el usuario vea el contenido de otros usuarios.

Convertir videos a formatos compatibles con HTML5

Muchas veces me he encontrado en la situación de necesitar colocar un video en un sitio web y no contar con el mismo en un formato adecuado. Afortunadamente en cualquier distro GNU/Linux contamos con la navaja Suiza de la multimedia, ffmpeg.

En este artículo de MDN encontramos una revisión muy completa sobre este tema y cuáles son los contenedores compatibles con HTML5, se reducen a 3. El formato MP4, que aunque propietario es el más difundido y soportado; el WEBM, completamente libre menos conocido; y el OGG también libre pero menos utilizado.

Sobre el contenedor MP4, tampoco es cualquiera, tiene que tener los streams en códecs específicos. El vídeo debe estar en H.264 baseline profile ya que le exige menos capacidad de procesamiento a la máquina del usuario. Un vídeo en H.264 High profile probablemente también podrá ser visualizado, pero en un dispositivo con baja capacidad de procesamiento, un teléfono de gama baja o incluso una laptop con un procesador atom por ejemplo podrán empezar a visualizarlo y luego de algunos minutos no podrán continuar la reproducción del vídeo o se ralentizará el dispositivo. El audio debe estar en formato AAC. También alguno navegadores soportan que el audio este en MP3, pero no son todos.

En esta tabla se resume los formatos de video compatibles con HTML5.

Contenedor (video codec / audio codec)ChromeFirefox (Gecko)Internet ExplorerOperaSafari
WebM (VP8 / vorbis)6.04.09.010.63.1
WebM (VP9 / theora)29.028.0??
OGG (Theora / vorbis)3.5Sin soporte10.50Sin soporte
MP4 (H.264 / AAC)9.0
MP4 (H.264 / MP3)9.03.1

Para convertir un vídeo a MP4 con H.264 baseline tomando como base un MP4 con video H.264 en otro perfil y optimizado para reproducir vía web.

$ ffmpeg -i input-mp4-highprofile.mp4 -movflags faststart -vcodec libx264 -vprofile baseline -crf 18 -acodec copy output-mp4-baselineprofile.mp4

Para convertir un video a WEBM tomando como base un video MP4 (aunque puede ser cualquier tipo).

$ ffmpeg -i input.mp4 -vcodec libvpx -crf 10 -b:v 0 -acodec libvorbis -threads 4 output.webm

La velocidad de encoding es extremadamente lenta, entre 8-10 frames por segundo.