En este apunte describo cómo instalar una VM (máquina virtual) Linux que hará de router/firewall casero para conectar a Movistar Fusión Fibra + TV + VoIP. Es la “caja roja” en la imagen siguiente, se ejecutaba en mi hypervisor ESXi (usando como “base” VM Linux en ESXi). Nota: más adelante he abandonado ESXi y ahora uso KVM (con “base” VM Linux en KVM, esta vez con iSCSI), pero eso es otra historia…

NOTA: Este caso de uso como router de internet está descrito en el apunte Movistar Fusión Fibra + TV + VoIP con router Linux. En dicho apunte usé un Linux sobre Mac Mini, mientras que ahora el servidor lo virtualizo y el tráfico de las VLAN’s llega sin etiquetar (vlan-id).

ESXi-Docker-Router
 

Para empezar, como decía arriba, lo primero es duplicar la plantilla que documenté en este otro apunte: Gentoo VM y crear una máquina virtual nueva. La voy a llamar “Cortafuegix“, en alusión a la Aldea Gala de ASterix 🙂

Cortafuegix

Por cierto, hice algo parecido para mi máquina virtual para montar las aplicaciones que luego ejecuto en Docker, aunque no documento la instalación de Gentoo por ser muy parecida, amplía la imagen siguiente para echar un ojo a la configuración de la VM “Aplicacionix

Aplicacionix
 

La Red

Empiezo por el principio, la configuración de la red y vlan’s.

En casos como este es muy importante tener claro cual es el diseño físico de la red, qué NIC’s tenemos y qué NIC’s virtuales van a presentarse (desde ESXi) a la VM. Voy a configurar las vNICs con nombres predecibles, con IPs estáticas (sin dhcp) y que no cambie nada al hacer reboot.

NOTA: Mi plantilla usaba cliente DHCP así que lo paro y lo deshabilito: systemctl stop dhcpcd.service y systemctl disable dhcpcd.service.


 
Conexión física en ESXi

Si empezamos por el diseño físico, es simple, mi Servidor casero, donde se ejecuta ESXi, tiene una única tarjeta de red, asi que conecto ese puerto al Switch externo por el cual entrega 4 x VLAN’s: 2 (iptv), 3 (voip), 6 (internet), 100 (intranet).

ESXiFisico

En el ESXi creo un único Virtual Switch con 4 x “Port Group’s”, uno por VLAN, que podré asociar a diferentes vNICs (virtual NIC’s) en las máquinas virtuales. Veamos un ejemplo en la figura siguiente: Virtual Switch, los “Port Groups” y su asociación a las vNIC’s de la máquina virtual “Cortafuegix”

ESXiNet-1

NOTA: Ya comenté en Movistar Fusión Fibra + TV + VoIP con router Linux que para este tipo de diseños es fundamental contar con un Switch Ethernet 10/100/1000 que tenga soporte de VLAN’s (802.1q) y Multicast (IGMP Snooping), y sobre todo que el Hardware de tu Servidor Casero tenga una NIC que soporte VLAN’s.


 
Conexiones ethernet en la VM

En esta configuración he decidido que sea el ESXi el que trate el VLAN-ID, de modo que el tráfico llegará “limpio” a las ma´quinas virtuales (sin vlanid). En la configuración de la VM “cortafuegix” creo varias tarjetas de red, todas con el driver E1000 y las asocio a los port groups. Veamos cómo recibimos dichas vNICs en la VM, cómo se ven en linux y si hace falta hacer algo más…

Hace tiempo se introdujo el concepto de “nombres de interfaces predecibles”, un servicio de udevd bien descrito upstream. Sin embargo, en mi caso, que quiero tener todo muy “atado”, prefiero asignar nombres específicos a cada una de las interfaces hardware que se le están presentando a la máquina virtual.

Conseguirlo es muy fácil, lo primero es que asignes direcciones MAC estáticas a cada una de las tarjetas, desde vSphere Client, en la configuración de la máquina virtual.

FixMac

A continuación creas un fichero con reglas para que udev cambie el nombre de las tarjetas usando dichas direcciones Mac y rearrancas la VM.

Truco: Ya que pones las MAC’s, aprovecha y que te digan algo, en mi caso he elegido que los dos últimos bytes coincidan con el número de la VLAN.

Tras el próximo arranque podemos observar cómo han cambiado los nombres de las interfaces.

GentooVM-Rules-1

 

Recuerda: Las vNICs van a recibir el tráfico “SIN” el VLAN-ID, no fue así en Movistar Fusión Fibra + TV + VoIP con router Linux.


 
systemd-networkd

Para asignar las direcciones IP a las tarjetas utilizo el servicio systemd-networkd. Hace falta crear un fichero para cada interfaz debajo de /etc/systemd/network, el nombre puede ser cualquiera pero debe terminar en .network:

Notarás que no he especificado ningún gateway por defecto, ni tampoco el DNS server. Lo he hecho a proposito, el router por defecto se establecerá al activar PPPoE y la información del DNS Server la pondré de manera estática en el /etc/resolv.conf.

Puedes ejecutar systemctl start systemd-networkd y ver el estado de las interfaces con el comando networkctl. Dejo a continuación algunos comandos de referencia, aunque te recomiendo que esperes a leer todo el apunte porque he creado múltiples ficheros de apoyo para configurar “systemd” y el arranque de los servicios:

  • Arrancar durante el boot: systemctl enable systemd-networkd
  • Arrancar manualmente: systemctl start systemd-networkd
  • Re-arrancar (si cambias algo): systemctl restart systemd-networkd
  • Verificar: networkctl

 
PPP

Instalo el paquete PPP (recordemos que necesitamos PPPoE por el interfaz VLAN6 para recibir la IP desde Movistar). Antes tendrías que habilitar varios parámetros en el kernel, compilarlo y hacer reboot. Mi plantilla ya está preparada (.config), así que no tengo que hacer nada, me lo salto.

Preparo parámetros USE e instaloo net-dialup/ppp:

Creo el fichero /etc/systemd/system/ppp_wait@.service

Configuramos el fichero /etc/ppp/pap-secrets

Creo un "peer" llamado movistar:

Programo que el servicio arranqeu durante el boot (usar \@movistar en el nombre del servicio):

 
DHCLIENT

Necesito activar un cliente DHCP para recibir la IP de VoIP en el interfaz VLAN3. En vez de usar el cliente embebido de systemd-networkd voy a usar el programa "dhclient". El cliente embebido en systemd-networkd es muy intrusivo, manipula la tabla de routing e impide que RIPD (más adelante) instale sus rutas.

La instalación y configuración de DHCLIENT la dejo para más adelante, viene incluido con el DHCP Server.

 

El Firewall

El “cortafuegos” lo haré con el framework netfilter del kernel y un montón de comandos iptables, el logging será con ulogd, un daemon que se ejecuta en el “userspace” especialmente diseñado para netfilter/iptables.

Preparo las variables USE y ejecuto la instalación de ulogd.

A continuación un ejemplo de /etc/ulogd.conf, con múltiples stacks. Lee la documentación oficial para enteneder cómo funciona.

También tienes que configurar el Kernel para soportar netfilter (iptables), compilarlo y hacer reboot. Mi plantilla ya está preparada (.config), así que no tengo que hacer nada, me lo salto. Los scripts de iptables se instalaron con mi plantilla, en cualquier caso si lo necesitas, se instalan así: emerge -v iptables.

No voy a explicar iptables por completo pero dejo aquí un vistazo sobre cómo he hecho para cargar las reglas durante el boot. El comando “iptables” no es un daemon en sí, se trata de un programa que permite instalar Rules (reglas) en el Kernel. El truco consiste en ejecutar muchas veces iptables introduciendo una a una las reglas y cuando todo funciona salvas dichas “reglas o estado” en una fichero externo (con el comando iptables-save) y en el siguiente boot las recuperas desde dicho fichero (con iptables-restore).

Eso sería lo normal, pero en mi caso prefiero ejecutar dos scripts que tienen todos esos comandos “iptables” durante el boot del equipo, uno antes de que se active la red y otro “después” de que se activa la red.

Creo el directorio donde dejaré los script mkdir /root/firewall y los ficheros de servicios systemd

Este es el primer script. Como decía se ejecutará antes de que haya red e interfaces disponibles, pero no pasa nada, se instalarán las reglas correctamente. El objetivo es que haya reglas activa según se “enciende” el networking :-).

El segundo script es el siguiente, se ejecutará tras tener toda la red y sus interfaces activas.

Activa los servicios para que arranquen durante el boot (de momento no hagas reboot)

  • Servicio Pre-Red: systemctl enable router_iptables_pre_net.service
  • Servicio Post-Red: systemctl enable router_iptables_post_net.service

 
Alternativa a iptables

Si esto de iptables es demasiado duro… échale un ojo a pfSense, un proyecto fantástico que conocí hace poco: Un Firewall Open Source “probado” con un interfaz sencillo Web para su administración, que podrías ejecutar como máquina virtual en el ESXi.

networking

 

Servidores DNS y DHCP

El siguiente paso es instalar BIND y DHCP para tener un Servidor de nombres y uno de direcciones IP. Dejo unos ejemplos “cuasi” reales para que te sirvan de “munición” en tu propia configuración.

DNS Server

Si tienes un equipo Linux encendido 24 horas en tu intranet te recomiendo activar tu propio DNS Server, podrás asignar nombres a las direcciones IP y junto con un DHCP Server asignar direcciones IP estáticas sobre la base de la dirección MAC (usando el nombre DNS). Prepara el fichero named.conf y un par de ficheros más para tu dominio privado. Dejo un ejemplo para un dominio interno que he llamado “parchis.org”. La ventaja que tiene es que hace de acelerador/proxy, cuando consultes un dominio desoncocido pues se irá a internet a buscar la respuesta.

Zona interna (parchis.org)

Resolución inversa

Tanto este servidor (él mismo) como cualquier otro equipo de la Intranet debe apuntar a él para las consultas DNS, y como decía antes si es necesario él irá a internet a buscar las respuestas.

Activo el servicio DNS Server, no necesitas crear ningún fichero .service, en esta ocasión voy a usar el que trae el sistema (se encuentran en /usr/lib64/systemd/system).

  • Servicio DNS: systemctl enable named.service

 
DHCP Server

El DHCP Server también es muy sencillo de configurar, se basa en el fichero /etc/dhcp/dhcpd.conf y /etc/conf.d/dhcp.

Creo el Unit porque el que trae el sistema no me vale:

Activo el servicio DHCP Server.

  • Servicio DHCP Server: systemctl enable dhcpd.service

 
DHClient para vlan3

Lo comenté antes, hay que activar un cliente DHCP para la IP de VoIP en el interfaz VLAN3, no uso el embebido de systemd-networkd sino el "dhclient" que viene con el DHCP Server que acabamos de instalar.

Creo un unit specífico:

IMPORTANTE: Creo el fichero de configuración de dhclient y sobre todo el fichero de “hook”, no te olvides o te instalará una ruta por defecto adicional que te “destrozará” el routing 🙂

Activo el servicio DHCP Cliente.

  • Servicio DHCP Cliente vlan3: systemctl enable dhclient.service

 

Servicios adicionales

El resto de servicios (igmpproxy, udpxy, etc..) ya los documenté en este apunte donde explico cómo instalarlos y configurarlos. En aquella ocasión usaba openrc para arrancar los servicios, dejo aquí los ficheros que necesitas para systemd.

igmpproxy.service

udpxy.service

zebra.service

ripd.service

  • Servicio igmpproxy: systemctl enable igmpproxy.service
  • Servicio udpxy: systemctl enable udpxy.service
  • Servicio zebra: systemctl enable zebra.service
  • Servicio ripd: systemctl enable ripd.service

 

Directorio “run”

Los directorios en /run y /var/run que necesitan los programas anteriores no se crean con systemd, así que he montado un “service” y un pequeño script para solucionarlo.

Activo el servicio:

  • Servicio creación de directorios: systemctl enable router_pre.service

 

Herramienta de verificación

Para terminar te dejo una herramienta que me he preparado para ver si todo va bien…

router-verifica