Monta una conexión de respaldo en opnsense

Esta semana pasada he sufrido la experiencia traumática de tener que mudarme de oficina… El casero ha dicho que no renueva el contrato y no me ha quedado más remedio que mudarme (con 14 años de trastos a mis espaldas) a otra oficina diferente… Y, aunque no soy muy tiquismiquis hay una cosa que siempre necesito… Internet.

Tengo contratado masmovil desde hace muchos años, 1Gb de fibra y una IP fija, cosas que me vienen muy bien para el tipo de cosas que tengo que hacer, y quiero seguir manteniendo estas cosas (y el número de teléfono que viene asociado a la conexión), así que indiqué a Masmovil el día del traslado y me confirmaron que ese mismo día pasaría por la nueva oficina un instalador a realizar el paso de mi conexión a esa nueva oficina.

Ahora bien, resulta que la dirección estaba mal registrada o que habían separado en oficinas lo que antes era solo un edificio o que-se-yo, el caso es que solo daba servicio movistar y el primer instalador me dijo que solicitaban el cambio y que ya me avisarían cuando estuviese la cosa. Al día siguiente me vino otro instalador que me dejó todo correctamente instalado perjurando que el instalador anterior podía haberlo hecho el otro día sin problemas (en fin…) al cabo de unos minutos ya tenía otra vez mi IP fija y mi casi-1g con los que he estado funcionando hasta ayer.

Ayer los vecinos llamaron a su instalador de movistar porque no tenían conexión y resulta que lo que pasaba es que ellos estaban (vete tu a saber porqué) enchufados a la roseta que estaba en mi oficina y, claro, al cambiarla yo el cable que iba a su router ya no estaba conectado (ni la conexión activa)… El caso es que el instalador se encabronó con el tema de tener que tirar ellos el cable otra vez (ya me dirás qué tendrían que hacer si no había fibra que llegase a esa oficina) y no se lo que hizo que me dejó a mi sin conexión (y estoy seguro que algo podría haber hecho para mantenerla). El caso es que llevo desde ayer a medio día sin conexión a internet. Puse la incidencia, me dijeron que era cosa de fuera y que ya lo arreglarían (hace más de 28 horas de eso)… Y como yo tengo que trabajar pues no me ha quedado más remedio que usar un router 4G que tenía por aquí y contratar una SIM con gigas para poder tener algo de internet mientras tanto.

Como la wifi solo la puedo usar desde móviles y portátiles y yo quería usar mi torre (y tener conectividad en general) me puse a ver si era sencillo poner esa conexión como fallback en el router opnsense que monté con un ordenador chino (bastante bueno y con dos puertos SFP+ que me permiten llegar a 10Gb)… Y si, después de penar un poco (porque hay cosas que no están bien pulidas del todo) conseguí hacerlo funcionar. Estos son los pasos que di:

1.- Enchufar el router 4G a la salida ethernet que tenía libre mi ordenador-router (os pongo la foto de uno parecido)

En eth0 estaba el router de masmovil configurando este como DMZ para poder recibir el tráfico entrante y en eth1 la nueva conexión.

En SPF0 tenía conectado el router del resto de mi red.

2.- En opnsense doy de alta el interfaz nuevo (en este caso por dhcp)

3.- En System > gateways > configuration creo un gateway nuevo, le digo que active la monitorización del gateway y le pongo la IP de un servidor dns fiable (como 8.8.4.4) y le pongo como IP la IP del router 4G (192.168.0.1 en mi caso).

4.- El gateway existente lo modifico para habilitar el monitoreo y añado como IP la 8.8.8.8 (puede ser cualquiera mientras sea diferente de la anterior)

5.- En system > settings > general añado estos dos DNS como DNS Servers y les asocio a cada uno el gateway correspondiente y activo la opción «Allow default gateway switching»

6.- En System > gateway > group creo un grupo nuevo, le pongo un nombre y hago que el interfaz de la WAN principal sea Tier1 y de la secundaria Tier2, ponemos Trigger Level a «Packet Loss or high latency» y una descripción adecuada (yo también puse Pool Options a Round Robin, pero eso no es tan importante)

7.- En Firewall > rules > LAN (o como llaméis a vuestro interfaz de red local) modificamos la configuración de la regla genérica que permite todo para indicar que el gateway será el nuevo grupo que acabamos de crear

8.- Por último, y esto lo he descubierto después de mucho tiempo, la generación automática de reglas NAT > Outbound no es perfecta y tuve que añadir una regla para que permitiese todo el tráfico desde la WAN2 indicando que su dirección de NAT sería la de WAN2

Y, en principio, esto es todo… Haced vuestras pruebas de ping, mtr y demás y veréis que cuando está caída la conexión principal saldréis a internet por la secundaria… Espero que masmovil me lo arregle pronto que los GB de la tarjeta sim ya se me están gastando. Grrr.

Usando GPU en Proxmox

Quizá todavía no lo conceis, pero Proxmox es el software definitivo si queréis montar vuestra propia infraestructura en casa (o en vuestra empresa), es un hypervisor que os permite tener vuestra propia «nube» creando máquinas virtuales, contenedores y gestionando almacenamiento, backups y alta disponibilidad.

Yo llevo unos meses con esto, desde que me compré y quise dar uso, unas placas chinas para aprovechar los Xeon de segunda mano que ahora se encuentran tan baratos y, la verdad, es como tener un AWS particular (salvando muuuuchas diferencias). El caso es que lo único que me quedaba por probar era cómo tener una máquina virtual controlada por proxmox que me permitiese hacer AI… Pero para eso necesitaba usar una GPU y esto no es taaan sencillo. Así que partamos de un servidor que tiene una tarjeta gráfica (en mi caso una RTX 3070) y veamos cómo configurar el ordenador para meterlo en un cluster proxmox estando preparado para tener VMs que usen esa GPU.

¿cual es el problema realmente?

El problema es que un hypervisor lo que hace es ejecutar máquinas virtuales a las que ha asignado cierta parte de sus recursos (disco, memoria, etc) y permitir el uso compartido de todo lo que se puede compartir. Por desgracia la GPU no se puede compartir de la misma manera que una CPU (hay algunos modelos que tienen una tecnología que se llama VGPU que parece que si permitirán hacerlo, pero por ahora las que tengo yo no). Es por eso que lo que se hace es pasarle a la máquina virtual todo el bus PCI en cuestión para que lo gestione de manera independiente. Para que esto se pueda llevar a cabo es importante que el SO de proxmox no esté usando este bus para nada (que no tenga los drives instalados siquiera). El servidor que yo he usado tenía video integrado y configuré la bios para que usase ese como video primario (y así instalé proxmox sin utilizar la tarjeta gráfica). Pasos importantes con la BIOS:

  • Activar la tarjeta integrada (si la tiene)
  • Activar todos los modos de multihilo VT-d y cualquier referencia a IOMMU

Dejo un enlace que lo explica para varias placas base.

Lo siguiente, desde el servidor con ya proxmox instalado será editar el arranque de grub poniendo lo siguiente en el archivo /etc/default/grub:

GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"

Y ejecuta después update-grub, tras lo cual tendrás que reiniciar la máquina.

Para comprobar que está todo activo ejecuta este comandos:

dmesg | grep -e DMAR -e IOMMU

El resultado tendría que ser algo como esto:

[    0.008366] ACPI: DMAR 0x000000007A29ED38 0000A8 (v01 INTEL  EDK2     00000002      01000013)
[    0.008390] ACPI: Reserving DMAR table memory at [mem 0x7a29ed38-0x7a29eddf]
[    0.098662] DMAR: IOMMU enabled
[    0.255710] DMAR: Host address width 39
[    0.255711] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[    0.255721] DMAR: dmar0: reg_base_addr fed90000 ver 1:0 cap 1c0000c40660462 ecap 19e2ff0505e
[    0.255723] DMAR: DRHD base: 0x000000fed91000 flags: 0x1
[    0.255727] DMAR: dmar1: reg_base_addr fed91000 ver 1:0 cap d2008c40660462 ecap f050da
[    0.255728] DMAR: RMRR base: 0x00000079d2f000 end: 0x00000079d4efff
[    0.255731] DMAR: RMRR base: 0x0000007b800000 end: 0x0000007fffffff
[    0.255733] DMAR-IR: IOAPIC id 2 under DRHD base  0xfed91000 IOMMU 1
[    0.255734] DMAR-IR: HPET id 0 under DRHD base 0xfed91000
[    0.255735] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping.
[    0.257485] DMAR-IR: Enabled IRQ remapping in x2apic mode
[    0.600499] DMAR: No ATSR found
[    0.600500] DMAR: No SATC found
[    0.600501] DMAR: IOMMU feature fl1gp_support inconsistent
[    0.600502] DMAR: IOMMU feature pgsel_inv inconsistent
[    0.600503] DMAR: IOMMU feature nwfs inconsistent
[    0.600504] DMAR: IOMMU feature pasid inconsistent
[    0.600505] DMAR: IOMMU feature eafs inconsistent
[    0.600506] DMAR: IOMMU feature prs inconsistent
[    0.600507] DMAR: IOMMU feature nest inconsistent
[    0.600508] DMAR: IOMMU feature mts inconsistent
[    0.600509] DMAR: IOMMU feature sc_support inconsistent
[    0.600509] DMAR: IOMMU feature dev_iotlb_support inconsistent
[    0.600510] DMAR: dmar0: Using Queued invalidation
[    0.600513] DMAR: dmar1: Using Queued invalidation
[    0.600990] DMAR: Intel(R) Virtualization Technology for Directed I/O

Donde lo relevante es el IOMMU enabled y Enabled IRQ remmaping. Si todo está ok podemos ver os grupos iommu con este comando:

pvesh get /nodes/pascal/hardware/pci --pci-class-blacklist ""

Que nos debería dar una salida como la siguiente:

??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
? class    ? device ? id           ? iommugroup ? vendor ? device_name                                                                             ? mdev ? su
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
...
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
? 0x030000 ? 0x2484 ? 0000:01:00.0 ?          2 ? 0x10de ? GA104 [GeForce RTX 3070]                                                                ?      ? 0x
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

Ahora nos falta asegurarnos de que proxmox no va a utilizar esta gpu y estaríamos casi listos para crear nuestra vm:

echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/iommu_unsafe_interrupts.conf
echo "vfio" >> /etc/modules
echo "vfio_iommu_type1" >> /etc/modules
echo "vfio_pci" >> /etc/modules
update-initramfs -u -k all
systemctl reboot

Comprobaremos que se carga vfio y pondremos en lista negra los drivers de nuestra gpu

dmesg | grep -i vfio
echo "options kvm ignore_msrs=1 report_ignored_msrs=0" > /etc/modprobe.d/kvm.conf
lspci -nn | grep 'NVIDIA'

Veremos los ids de nuestro dispositivo

01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104 [GeForce RTX 3070] [10de:2484] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation GA104 High Definition Audio Controller [10de:228b] (rev a1)

Y los usaremos para ponerlos en lista negra para los drivers posibles:

echo "options vfio-pci ids=10de:2484,10de:228b" >> /etc/modprobe.d/vfio.conf
echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nvidia" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nvidiafb" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nvidia_drm" >> /etc/modprobe.d/blacklist.conf
systemctl reboot

Y con esto ya está listo nuestro proxmox para compartir el PCI… Os recomiendo que si vais a unirlo a un cluster lo hagáis ahora, luego si creais una vm os va a ser más complicado. En cualquier caso, lo que queda es crear una máquina virtual y añadirle el pci de la tarjeta.

Para ello simplement creamos una máquina virtual, en mi caso digo que voy a instalar un linux y antes de arrancarla vamos al apartado de hardware y añadimos estos PCI:

Una vez arrancada la máquina e instalado el sistema operativo podemos comprobar si tenemos los drivers de nvida configurados ejecutando nvidia-smi

Así que ya tenemos una máquina con GPU para poder ejecutar nuestros trabajos de AI. Para ello podéis seguir estas instrucciones para instalar ollama o stable difussion en esta máquina virtual… Con la ventaja que aporta tenerlo controlado por Proxmox para hacer backups arrancarlo o pararlo a voluntad, monitorizarlo, etc.

Movistar Bloquea Cloudflare: Impacto en Webs y Solución

Aunque pareciese que no tiene nada que ver una cosa con otra, lo que es cierto es que estas últimas semanas han ido ligadas de la mano, pero de la manera mala. Dejadme que me explique.

El caso es que una de las aplicaciones que mantenemos empezó en un momento dado a recibir incidencias como si estuviese caída. El servidor estaba bien y yo desde mi oficina llegaba perfectamente, después de mucho indagar descubirmos que no se llegaba desde las conexiones Movistar u O2, además, lo que vimos es que había ya quejas de otros servidores que estaban afectados y solo tenían en común una cosa, que estaban detrás de Cloudflare. La cosa es que media internet utiliza los servicios de cloudflare, como CDN o como protección contra ataques DDOS o como proxy para ahorrar ancho de banda. Entendimos que debía ser un problema de enrutamiento de Movistar y desactivamos cloudflare momentaneamente a la espera de que lo solucionasen… Estamos hablando del día 3 de febrero.

Esto estuvo pasando durante toda la tarde, llegado un momento nos dijeron que ya volvía a funcionar (y que todo debería ser una avería, no nos dijeron otra cosa)

Peeero, casualidades de la vida, el día 8 se jugaba el derbi y, mira por donde, resulta que empezamos a recibir incidencias de nuevo… Vuelta a desactivar cloudflare y esperando de nuevo… Pero esta vez no lo arreglaron, el domingo seguía la cosa igual:

Y esto se quedó así hasta el lunes (qué curioso!) sin que nadie se dignase dar ninguna explicación ni disculpa. Miles de negocios perdidos y webs expuestas a ataques sin remedio por alimentar a las alimañas del deporte. Era tan evidente que ya se publicó como noticia en varios medios (https://hipertextual.com/2025/02/movistar-cloudflare-futbol). El caso es que estuvo funcionando bien hasta los partidos de champions en los que se repitieron cortes de 15 minutos alternos (igual esto había cantado demasiado).

¿Qué hacer?

Ahora nos surge el problema de qué hacer el fin de semana. No podemos irnos a descansar porque si nos vuelven a cortar cloudflare tendríamos que volver a desactivarlo a mano, así que, para todos aquellos que tengáis cloudflare os recomiendo usar algo como esto:

import requests
import subprocess
import os

def check_ip_reachable(ip):
    try:
        result = subprocess.run(['ping', '-c', '4', ip], capture_output=True, text=True, timeout=10)
        return result.returncode == 0
    except subprocess.TimeoutExpired:
        return False

def pause_cloudflare(domain, email, api_key):
    headers = {
        'X-Auth-Email': email,
        'X-Auth-Key': api_key,
        'Content-Type': 'application/json'
    }
    
    # Obtener el Zone ID
    zone_response = requests.get(f'https://api.cloudflare.com/client/v4/zones?name={domain}', headers=headers)
    zone_data = zone_response.json()
    
    if not zone_data['success']:
        print("Error al obtener el Zone ID")
        return False
    
    zone_id = zone_data['result'][0]['id']
    
    # Pausar el servicio
    pause_url = f'https://api.cloudflare.com/client/v4/zones/{zone_id}'
    pause_data = {'paused': True}
    
    response = requests.patch(pause_url, headers=headers, json=pause_data)
    result = response.json()
    
    if result['success']:
        print(f"Servicio pausado para el dominio {domain}")
        return True
    else:
        print(f"Error al pausar el servicio: {result['errors']}")
        return False

# Configuración
ip_to_check = "192.168.1.1"  # Reemplaza con la IP que quieres comprobar
domain = "ejemplo.com"  # Reemplaza con tu dominio
cloudflare_email = "[email protected]"  # Reemplaza con tu email de Cloudflare
cloudflare_api_key = "tu_api_key"  # Reemplaza con tu API key de Cloudflare

# Comprobar si la IP está accesible
if not check_ip_reachable(ip_to_check):
    print(f"La IP {ip_to_check} no está accesible. Pausando el servicio en Cloudflare...")
    if pause_cloudflare(domain, cloudflare_email, cloudflare_api_key):
        print("Servicio pausado exitosamente")
    else:
        print("No se pudo pausar el servicio")
else:
    print(f"La IP {ip_to_check} está accesible")

Este programita básicamente lo que hace es comprobar si una IP responde al ping y si no lo hace pone en pausa cloudflare para el dominio que queramos. Para ello solo hay que configurarlo con la IP, el dominio y los datos del API de cloudflare de nuestra cuenta. Lo recomendable es hacer un bucle que lo chequee cada cierto tiempo y (código que todavía no he hecho) que cuando vuelva la conectividad se vuelva a activar cloudflare.

Para mi estas actuaciones son completamente ilegales y atentan contra la neutralidad de la red. ¿Qué será lo siguiente? ¿Evitar que visitemos blogs de ideologías no aprobadas?, ¿Hacer inaccesible el porno? Por desgracia en mi casa usamos O2, pero igual tengo que cambiarme visto lo visto.

Monta un nodo bitcoin en 5 minutos

Bueno, cinco minutos es lo que dedicarás a configurar el software, pero luego tendrá que bajarse todo el blockchain y tardará una eternidad y se comerá todo el disco duro que tengamos disponible, pero bueno, vamos a intentar montar un nodo completo bitcoin para testnet (estamos probando) de manera que podamos hacerle consultas sin tener que llamar a otros servicios.

En un próximo post ya os contaré como hacer un explorador completo (con las mismas restricciones de tiempo que este). Por ahora vamos a preparar los materiales. Vamos a necesitar una máquina con ubuntu (o el sistema operativo de vuestra preferencia) y unos 200Gb de disco (para testnet, si queremos la blockchain de mainnet serán como 800Gb). Yo, en mi caso lo he hecho sobre un contenedor ubuntu en proxmox (ya os contaré qué tal con proxmox cuando tenga un rato).

Para crear mi contenedor he usado un script de la comunidad (aqui) pero vosotros podéis usar un ordenador de casa o una máquina virtual que pueda ejecutar docker y docker compose.

Yo la he configurado con 4 CPUs y 4Gb de memoria y me ha servido perfectamente. No os olvidéis de tener los 200Gb disponibles y montados en algún sitio de vuestra máquina. Una vez que tenemos docker y docker compose instalados y funcionando solo tenemos que crear un docker-compose.yml con este contenido:

services:
  bitcoin-testnet:
    image: bitcoin/bitcoin:28.0rc1
    container_name: bitcoin-testnet
    ports:
      - "18443:18443"
      - "18444:18444"
    command:
      - -printtoconsole
      - -testnet=1
      - -rest
      - -rpcbind=0.0.0.0
      - -rpcallowip=0.0.0.0/0
      - -rpcport=18443
      - -rpcuser=miusuario
      - -rpcpassword=mipass
      - -server
      - -txindex
    volumes:
      - /bitcoin-data:/home/bitcoin/.bitcoin
    restart: always

En este caso nos vamos a bajar una imagen preconfigurada de bitcoin (aunque si no os fiáis siempre podéis compilar la vuestra sacando el Dockerfile de github. Abriremos los puertos 18443 y 18444 para poder acceder al nodo desde fuera (recordad, si tenéis nat hacer una redirección del puerto en el router). Además, tenemos nuestro disco con 200Gb en el directorio /bitcoin-data y lo montamos en /home/bitcoin/.bitcoin en la imagen.

Las siguientes opciones son para ver el log en consola, usar testnet, activar el RPC por rest y enlazarnos con todas las IPs de la imagen. Además, configuramos que se usará un usuario miusuario con password mipass, se ejecutará como servidor y vamos a mantener índices de todo el blockchain…

Y con esto ya podemos lanzarlo:

docker compose up -d

Si todo va bien en unas cuantas (muchas) horas ya tendríamos una copia de la blockchain de testnet y podremos preguntar, por ejemplo, cual es el último bloque (suponiendo que nuestra máquina tenga la IP 192.168.1.55) usando curl, por ejemplo:

curl --user miusuario:mipass --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockcount", "params": []}' -H 'content-type: text/plain;' http://192.168.1.55:18443

Que nos devolvería algo como esto (el número de bloque, obviamente) será distinto en vuestro caso:

{"result":3774033,"error":null,"id":"curltest"}

Y, lo dicho, intentaré que el próximo post sea de cómo hacer un explorador de testnet que podamos utilizar via web… Id preparando más disco duro.

Publica en internet como un pro sin contratar hosting

O, para los que quieren saber de qué vamos a hablar aquí, de cómo usar los tuneles de cloudflare para exponer una web al mundo que está corriendo en uno de nuestros ordenadores (sin IP fija ni nada).

Supongamos que acabamos de crear nuestra aplicación (o todavía la estamos creando) y queremos enseñársela al mundo (o a nuestro cliente, que para el caso es lo mismo). Hasta ahora, si no teníamos una IP fija lo más habitual era tener que subir todo a un hosting (más caro o más barato) e ir actualizando allí el código cada vez que hacíamos algún cambio.

Cuando queramos pasar a producción una web con miles de millones de accesos (sic.) pues probablemente no nos importe gastarnos el dinero en un hosting decente, o instalarnos en la nube (AWS, GCE o Azure), pero para hacer experimentos o para ejecutar cosas en nuestra casa esto no hace falta… Y menos si tenemos en cuenta que hay opciones gratuitas para evitarlo.

Vayamos al tajo… Imaginemos que tenemos un ordenador donde estamos trabajando y que tiene la IP 192.168.1.35 y que, obviamente, podemos ver nuestra web en http://localhost (desde nuestro propio ordenador) o desde http://192.168.1.35 desde cualquier otro ordenador de nuestra casa. Supongamos también que hemos comprado un dominio «undominio.org» por ejemplo.

Lo siguiente será crear una cuenta en cloudflare, simplemente accedemos a cloudflare.com y nos registramos, una vez registrados damos de alta el dominio que tenemos (probablemente tendremos que cambiar los dns en nuestro proveedor de dominios, a no ser que lo hayamos comprado en el mismo cloudflare) y cuando nos informe de que ya estamos administrando el dominio podemos empezar con la parte del tunel… Para ello vamos a seleccionar Zero Trust en el panel de la izquierda:

Y esto nos dará acceso (si te pide datos de tarjeta no te preocupes, puedes seleccionar el plan gratuito y no se te cobrará nada) terminarás en esta pantalla:

Ahora seleccionamos redes-> tunnels

Y damos al botón crear nuevo tunel. Nos dará dos opciones y seleccionamos Cloudflared

Nos pedirá asignar un nombre al tunel y luego nos da las opciones para instalar cloudflared. Tienes que seleccionar el sistema operativo en el que tienes la web corriendo y la arquitectura. En mi caso lo tengo corriendo en un linux, así que simplemente tengo que copiar el código y ejecutarlo en una consola:

Una vez instalado y puesto a funcionar en nuestra máquina local, nos aparecerá en la lista de conectores:

Ahora toca elegir un subdominio o ruta para publicar nuestra web y la url local donde se encuentra la web (en mi caso estoy publicando la web de inteligencia artificial que ya montamos en uno de los posts anteriores:

Y con esto ya tenemos publicada la web en https://ia.undominio.org sin haber salido de nuestro ordenador…

La verdad es que esto del Zero trust tiene muchas más utilidades además de los túneles, no dejes de revisar todas las cosas interesantes que se pueden hacer (como verás hasta te has ahorrado el tema de los certificados y demás…)

Así que, ya sabes, anímate a publicar en internet lo que quieras sin tener que migrarte a la nube…