<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es">
    <title>Nezzontli - Spanish</title>
    <subtitle>Bitácora personal de Alejandro B.E.: tecnología, física, sistemas resilientes y fotografía analógica.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://nezzontli.xyz/es/tags/spanish/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://nezzontli.xyz"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-07-16T00:00:00+00:00</updated>
    <id>https://nezzontli.xyz/es/tags/spanish/atom.xml</id>
    <entry xml:lang="es">
        <title>Servidor personal: Debian + Docker, no FreeBSD</title>
        <published>2026-07-16T00:00:00+00:00</published>
        <updated>2026-07-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            B.E. Alejandro
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://nezzontli.xyz/es/blog/servidor/"/>
        <id>https://nezzontli.xyz/es/blog/servidor/</id>
        
        <content type="html" xml:base="https://nezzontli.xyz/es/blog/servidor/">&lt;h2 id=&quot;contexto&quot;&gt;Contexto&lt;&#x2F;h2&gt;
&lt;p&gt;Este post reemplaza una entrada anterior que describía el plan original: FreeBSD, jails, bastilleBSD. Ese plan no se ejecutó así. Lo que terminó corriendo en la máquina reusada (hostname &lt;code&gt;pcale&lt;&#x2F;code&gt;) es &lt;strong&gt;Debian 13 (Trixie)&lt;&#x2F;strong&gt; con todo containerizado en &lt;strong&gt;Docker&lt;&#x2F;strong&gt;, un stack por servicio en &lt;code&gt;docker-compose.yml&lt;&#x2F;code&gt; separados, sin hypervisor ni jails.&lt;&#x2F;p&gt;
&lt;p&gt;La razón del cambio fue práctica: Docker Compose me da aislamiento por servicio sin la curva de aprendizaje adicional de jails&#x2F;bhyve, y el ecosistema de imágenes ya resueltas (linuxserver, imágenes oficiales) redujo tiempo de instalación a casi cero comparado con compilar todo desde ports.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;infraestructura-base&quot;&gt;Infraestructura base&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SO:&lt;&#x2F;strong&gt; Debian 13 (Trixie), kernel 6.12.x&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Actualizaciones:&lt;&#x2F;strong&gt; &lt;code&gt;unattended-upgrades&lt;&#x2F;code&gt; para parches de seguridad automáticos&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Todo lo demás vive en contenedores&lt;&#x2F;strong&gt; — cada servicio tiene su propio &lt;code&gt;docker-compose.yml&lt;&#x2F;code&gt; bajo &lt;code&gt;&#x2F;home&#x2F;ale&#x2F;&amp;lt;servicio&amp;gt;&#x2F;&lt;&#x2F;code&gt;, así config, volúmenes y upgrades quedan aislados por app&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;acceso-y-red&quot;&gt;Acceso y red&lt;&#x2F;h2&gt;
&lt;p&gt;No hay puertos abiertos al público en el router. El acceso normal es vía &lt;strong&gt;Tailscale&lt;&#x2F;strong&gt;: cada servicio interno se publica con un hostname propio y HTTPS real usando Tailscale Services:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;tailscale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; serve&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;service&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-option z-shell&quot;&gt;=&lt;&#x2F;span&gt;svc:&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;nombre&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-terminator z-file-descriptor z-shell&quot;&gt;-&lt;&#x2F;span&gt;-bg&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;https&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-option z-shell&quot;&gt;=&lt;&#x2F;span&gt;443 http:&#x2F;&#x2F;localhost:&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;puerto&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;tailscale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; serve&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;service&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-option z-shell&quot;&gt;=&lt;&#x2F;span&gt;svc:&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;nombre&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-terminator z-file-descriptor z-shell&quot;&gt;-&lt;&#x2F;span&gt;-bg&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;http&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-option z-shell&quot;&gt;=&lt;&#x2F;span&gt;80 http:&#x2F;&#x2F;localhost:&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;puerto&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esto da URLs como &lt;code&gt;https:&#x2F;&#x2F;nextcloud.tail32b955.ts.net&lt;&#x2F;code&gt;, con certificado válido, sin recordar puertos. Un par de servicios sí salen a internet público, pero vía &lt;strong&gt;Cloudflare Tunnel&lt;&#x2F;strong&gt; (&lt;code&gt;cloudflared&lt;&#x2F;code&gt;, conexión saliente únicamente, nada expuesto en el router) — el caso principal es PeerTube en &lt;code&gt;tube.richard69.lat&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Perímetro:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;SSH solo con clave, llave de seguridad física (YubiKey), &lt;code&gt;X11Forwarding&lt;&#x2F;code&gt; desactivado&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ufw&lt;&#x2F;code&gt; en default-deny, la mayoría de servicios restringidos a LAN (&lt;code&gt;192.168.68.0&#x2F;24&lt;&#x2F;code&gt;) + Tailscale (&lt;code&gt;100.0.0.0&#x2F;8&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;fail2ban&lt;&#x2F;code&gt; en el jail de SSH (maxretry 3, ban 24h)&lt;&#x2F;li&gt;
&lt;li&gt;Vaultwarden llegó a tener un hostname público en el tunnel; se sacó por completo y ahora es Tailscale-only&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;servicios-corriendo&quot;&gt;Servicios corriendo&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Nube y datos personales&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Nextcloud&lt;&#x2F;strong&gt; — almacenamiento personal, también sirve como fuente de la biblioteca de Calibre-web (apunta directo a &lt;code&gt;Documents&#x2F;Libros&lt;&#x2F;code&gt; sin duplicar archivos)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Immich&lt;&#x2F;strong&gt; — fotos&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Vaultwarden&lt;&#x2F;strong&gt; — gestor de contraseñas (servidor compatible con Bitwarden), solo por Tailscale&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Calibre-web&lt;&#x2F;strong&gt; — lector&#x2F;biblioteca de ebooks&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Media&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Jellyfin&lt;&#x2F;strong&gt; — servidor de medios (películas, series, música)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;qBittorrent + Radarr + Sonarr + Prowlarr&lt;&#x2F;strong&gt; — el stack *arr completo: indexers → búsqueda → descarga → importación, aterrizando directo en la biblioteca de Jellyfin, que se refresca sola al importar&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Navidrome&lt;&#x2F;strong&gt; — streaming de música&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;spotiflac&lt;&#x2F;strong&gt;, &lt;strong&gt;AudioMuse AI&lt;&#x2F;strong&gt; — utilidades de música&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;PeerTube&lt;&#x2F;strong&gt; — instancia propia y federada de video (&lt;code&gt;tube.richard69.lat&lt;&#x2F;code&gt;), con una imagen parcheada a mano (ver abajo)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Todo el lado de descargas (qBittorrent, Radarr, Sonarr, Prowlarr, spotiflac) corre con &lt;code&gt;network_mode: container:mullvad-exit-vpn&lt;&#x2F;code&gt;, compartiendo el namespace de red de un único contenedor &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;qdm12&#x2F;gluetun&quot;&gt;gluetun&lt;&#x2F;a&gt;, así ese tráfico —y solo ese— sale por un exit de Mullvad vía WireGuard.&lt;&#x2F;p&gt;
&lt;p&gt;Un extra que armé sobre esto: un script que convierte un canal de PeerTube seguido en una biblioteca de Jellyfin de archivos &lt;code&gt;.strm&lt;&#x2F;code&gt; (punteros a la URL del HLS del video original). Jellyfin los reproduce en directo desde la instancia origen sin que el archivo toque el disco del servidor.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Utilidades&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Glance&lt;&#x2F;strong&gt; — dashboard único: bookmarks, RSS, clima, chequeos de salud de cada servicio, buscador&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;4get&lt;&#x2F;strong&gt; — metabuscador privado, también el buscador embebido en Glance&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;ntfy&lt;&#x2F;strong&gt; — notificaciones push self-hosted (alertas del servidor, watchdog de la VPN, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Uptime Kuma &#x2F; Beszel&lt;&#x2F;strong&gt; — monitoreo, con umbrales de alerta mandando a ntfy&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prosody&lt;&#x2F;strong&gt; — mensajería XMPP&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Forgejo&lt;&#x2F;strong&gt; — Git self-hosted (donde vive este mismo blog)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;problemas-encontrados-y-soluciones&quot;&gt;Problemas encontrados (y soluciones)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;network_mode: container:X&lt;&#x2F;code&gt; no se re-resuelve solo.&lt;&#x2F;strong&gt; Docker fija esa referencia a un &lt;em&gt;container ID&lt;&#x2F;em&gt; en el momento de crear el contenedor. Si gluetun se recrea (&lt;code&gt;docker compose up --force-recreate&lt;&#x2F;code&gt;, o cualquier reinicio del stack), todo lo que comparte su netns (qBittorrent, Radarr, Sonarr, Prowlarr, spotiflac) queda apuntando a un namespace huérfano. El síntoma es engañoso: el contenedor se ve &lt;code&gt;Up (healthy)&lt;&#x2F;code&gt; y su proceso interno escucha bien desde adentro, pero nada llega desde afuera. Fix: force-recreate de cada contenedor afectado, no alcanza con &lt;code&gt;docker restart&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;*&lt;em&gt;La ruta de descarga de un &lt;em&gt;arr no puede ser su propia root folder.&lt;&#x2F;em&gt;&lt;&#x2F;em&gt; Si la categoría de qBittorrent apunta al mismo path que el root folder de Radarr&#x2F;Sonarr, la app no puede distinguir “todavía bajando” de “ya importado” y tira &lt;code&gt;DownloadClientRootFolderCheck&lt;&#x2F;code&gt;. Solución: carpetas de staging separadas (&lt;code&gt;&#x2F;media&#x2F;downloads&#x2F;movies&lt;&#x2F;code&gt;, &lt;code&gt;&#x2F;media&#x2F;downloads&#x2F;shows&lt;&#x2F;code&gt;), Radarr&#x2F;Sonarr importan por hardlink desde ahí al root folder real.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;ntfy en iOS necesita un &lt;code&gt;base-url&lt;&#x2F;code&gt; alcanzable.&lt;&#x2F;strong&gt; iOS no puede recibir contenido completo en el push directamente (limitación de APNs) — el teléfono hace polling al &lt;code&gt;base-url&lt;&#x2F;code&gt; del propio servidor después de recibir un push genérico de “new message”. Si ese &lt;code&gt;base-url&lt;&#x2F;code&gt; apunta a un dominio muerto, la notificación queda vacía sin ningún error visible en ningún lado.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;PeerTube solo acepta thumbnails remotos en JPEG.&lt;&#x2F;strong&gt; El validador de videos federados de PeerTube rechaza en silencio cualquier video cuyo thumbnail remoto sea PNG o WebP. Lo resolví con un parche chico horneado en una imagen Docker custom — hay que reconstruirla (no solo &lt;code&gt;docker compose pull&lt;&#x2F;code&gt;) en cada actualización de PeerTube o el parche desaparece sin avisar.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;que-falta-por-hacer&quot;&gt;Qué falta por hacer&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare Access delante de Uptime Kuma si algún día se tunelea al público&lt;&#x2F;li&gt;
&lt;li&gt;Reglas de &lt;code&gt;ufw&lt;&#x2F;code&gt; para un par de servicios más nuevos (4get, AudioMuse) que hoy solo responden desde localhost&lt;&#x2F;li&gt;
&lt;li&gt;Un manual real de recuperación ante desastres — por ahora ese conocimiento vive en mis notas, no en un documento&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;idea-central&quot;&gt;Idea central&lt;&#x2F;h2&gt;
&lt;p&gt;El objetivo cambió de “aprender FreeBSD a fondo” a “tener servicios propios corriendo de forma confiable, con el mínimo de superficie expuesta al público”. Docker Compose y Tailscale resultaron el camino más corto ahí. FreeBSD y jails siguen siendo un proyecto que me interesa, pero para otro momento — ver el post de &lt;a href=&quot;https:&#x2F;&#x2F;nezzontli.xyz&#x2F;blog&#x2F;web&#x2F;&quot;&gt;OpenBSD&lt;&#x2F;a&gt; para la versión de “control total” aplicada a algo más chico (el hospedaje de este mismo sitio).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;referencias&quot;&gt;Referencias&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;tailscale.com&#x2F;kb&#x2F;&quot;&gt;Documentación de Tailscale&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;qdm12&#x2F;gluetun&quot;&gt;gluetun&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;glanceapp&#x2F;glance&quot;&gt;Glance&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wiki.servarr.com&#x2F;&quot;&gt;Servarr Wiki&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.joinpeertube.org&#x2F;&quot;&gt;Documentación de PeerTube&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>Uso de OpenBSD para hospedaje de página web</title>
        <published>2026-02-03T00:00:00+00:00</published>
        <updated>2026-02-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            B.E. Alejandro
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://nezzontli.xyz/es/blog/web/"/>
        <id>https://nezzontli.xyz/es/blog/web/</id>
        
        <content type="html" xml:base="https://nezzontli.xyz/es/blog/web/">&lt;h2 id=&quot;contexto-y-motivacion&quot;&gt;Contexto y motivación&lt;&#x2F;h2&gt;
&lt;p&gt;Decidí migrar el hospedaje de mi página web a OpenBSD como un ejercicio deliberado de control, simplicidad y seguridad.&lt;br &#x2F;&gt;
No fue una decisión basada en rendimiento, escalabilidad comercial ni automatización extrema, sino en comprensión total del sistema.&lt;&#x2F;p&gt;
&lt;p&gt;OpenBSD obliga a entender cada archivo de configuración, cada servicio activo y cada permiso. No oculta complejidad: la expone. Ese fue el motivo central de esta migración.&lt;&#x2F;p&gt;
&lt;p&gt;El objetivo era claro: un servidor auditable, predecible y mínimo.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;infraestructura-y-vm&quot;&gt;Infraestructura y VM&lt;&#x2F;h2&gt;
&lt;p&gt;El servidor corre en una máquina virtual alquilada (VPS) de bajo costo, suficiente para contenido estático y servicios mínimos.&lt;&#x2F;p&gt;
&lt;p&gt;Características generales de la VM:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;1 vCPU&lt;&#x2F;li&gt;
&lt;li&gt;1–2 GB de RAM&lt;&#x2F;li&gt;
&lt;li&gt;Almacenamiento SSD&lt;&#x2F;li&gt;
&lt;li&gt;IP pública dedicada&lt;&#x2F;li&gt;
&lt;li&gt;Acceso root inicial para bootstrap&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;El proveedor no es relevante: OpenBSD no depende de features del host. El sistema se mantiene portable y reproducible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;eleccion-del-stack&quot;&gt;Elección del stack&lt;&#x2F;h2&gt;
&lt;p&gt;El stack fue elegido conscientemente para reducir superficie de ataque:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Sistema operativo: OpenBSD&lt;&#x2F;li&gt;
&lt;li&gt;Servidor web: httpd (nativo)&lt;&#x2F;li&gt;
&lt;li&gt;HTTPS: acme-client (Let’s Encrypt)&lt;&#x2F;li&gt;
&lt;li&gt;Generador estático: Zola&lt;&#x2F;li&gt;
&lt;li&gt;Tema: Duckquill (modificado)&lt;&#x2F;li&gt;
&lt;li&gt;Repositorio: Git + GitHub&lt;&#x2F;li&gt;
&lt;li&gt;Acceso remoto: SSH con YubiKey (OpenPGP)&lt;&#x2F;li&gt;
&lt;li&gt;Servicio oculto: Tor (mirror .onion)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;No hay nginx, no hay docker, no hay paneles web, no hay Node en producción. Solo binarios del sistema base y archivos de texto.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;migracion-a-openbsd&quot;&gt;Migración a OpenBSD&lt;&#x2F;h2&gt;
&lt;p&gt;La migración incluyó:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Instalación limpia de OpenBSD&lt;&#x2F;li&gt;
&lt;li&gt;Configuración manual de red y DNS&lt;&#x2F;li&gt;
&lt;li&gt;Creación explícita de usuarios&lt;&#x2F;li&gt;
&lt;li&gt;Uso exclusivo de doas (sin sudo)&lt;&#x2F;li&gt;
&lt;li&gt;Servicios deshabilitados por defecto&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Separación clara entre: sistema (&#x2F;etc), contenido (&#x2F;var&#x2F;www), claves (&#x2F;etc&#x2F;ssl, &#x2F;etc&#x2F;acme). Nada se dejó “por default” sin entenderlo.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;servidor-web-con-httpd&quot;&gt;Servidor web con httpd&lt;&#x2F;h2&gt;
&lt;p&gt;El servidor web se configuró usando httpd nativo, sin módulos externos.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Configuración base simplificada:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;server &amp;quot;nezzontli.xyz&amp;quot; {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    listen on * port 80
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    root &amp;quot;&#x2F;htdocs&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    location &amp;quot;&#x2F;.well-known&#x2F;acme-challenge&#x2F;*&amp;quot; {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        root &amp;quot;&#x2F;acme&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        request strip 2
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;server &amp;quot;nezzontli.xyz&amp;quot; {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    listen on * tls port 443
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    root &amp;quot;&#x2F;htdocs&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    tls {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        certificate &amp;quot;&#x2F;etc&#x2F;ssl&#x2F;nezzontli.xyz.fullchain.pem&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        key &amp;quot;&#x2F;etc&#x2F;ssl&#x2F;private&#x2F;nezzontli.xyz.key&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;https-con-acme-client&quot;&gt;HTTPS con acme-client&lt;&#x2F;h2&gt;
&lt;p&gt;OpenBSD incluye acme-client en base, lo que elimina dependencias externas.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Flujo real:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Configurar httpd solo en HTTP&lt;&#x2F;li&gt;
&lt;li&gt;Resolver DNS correctamente (A records apuntando a la VM)&lt;&#x2F;li&gt;
&lt;li&gt;Ejecutar: &lt;code&gt;doas acme-client -v nezzontli.xyz&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Verificar creación de certificados en &#x2F;etc&#x2F;ssl&lt;&#x2F;li&gt;
&lt;li&gt;Habilitar TLS en httpd&lt;&#x2F;li&gt;
&lt;li&gt;Reiniciar servicio&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;No se usan scripts externos. La renovación se maneja vía cron del sistema.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;problemas-encontrados-y-soluciones&quot;&gt;Problemas encontrados (y soluciones)&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-error-404-en-acme-challenge&quot;&gt;1. Error 404 en ACME challenge&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Causa:&lt;&#x2F;strong&gt; httpd no estaba sirviendo correctamente &#x2F;var&#x2F;www&#x2F;acme.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Solución:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;doas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; mkdir&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;p&lt;&#x2F;span&gt; &#x2F;var&#x2F;www&#x2F;acme&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;doas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; chown&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;R&lt;&#x2F;span&gt; web:web &#x2F;var&#x2F;www&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;2-dns-no-propagado&quot;&gt;2. DNS no propagado&lt;&#x2F;h3&gt;
&lt;p&gt;Durante el primer intento, el dominio resolvía a múltiples IPs antiguas: &lt;code&gt;dig nezzontli.xyz +short&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Solución:&lt;&#x2F;strong&gt; Esperar propagación completa y eliminar registros conflictivos.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-confusion-con-dnssec&quot;&gt;3. Confusión con DNSSEC&lt;&#x2F;h3&gt;
&lt;p&gt;DNSSEC no es requisito para Let’s Encrypt HTTP-01. DNSSEC es independiente de TLS. No se activó en esta etapa.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;generacion-del-sitio-con-zola&quot;&gt;Generación del sitio con Zola&lt;&#x2F;h2&gt;
&lt;p&gt;El sitio es 100% estático.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Flujo básico:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;zola&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;doas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; rsync&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;delete&lt;&#x2F;span&gt; public&#x2F; &#x2F;var&#x2F;www&#x2F;htdocs&#x2F;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;No hay generación en runtime. No hay escritura desde el servidor web.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mirror-tor-onion&quot;&gt;Mirror Tor (.onion)&lt;&#x2F;h2&gt;
&lt;p&gt;Se configuró un Hidden Service de Tor como mirror del sitio.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&#x2F;etc&#x2F;tor&#x2F;torrc:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;HiddenServiceDir &#x2F;var&#x2F;tor&#x2F;hidden_service&#x2F;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;HiddenServicePort 80 127.0.0.1:80
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;httpd escucha solo en localhost para Tor:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;server &amp;quot;*&amp;quot; {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    listen on 127.0.0.1 port 80
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    root &amp;quot;&#x2F;tor&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Build específico para Tor:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;zola&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;base-url&lt;&#x2F;span&gt; http:&#x2F;&#x2F;&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;onion&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;.onion&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;doas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; rsync&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;delete&lt;&#x2F;span&gt; public&#x2F; &#x2F;var&#x2F;www&#x2F;tor&#x2F;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Integración Tor Browser (Onion-Location):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;html&quot; class=&quot;language-html z-code&quot;&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;z-text z-html z-basic&quot;&gt;&lt;span class=&quot;z-meta z-tag z-inline z-any z-html&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-begin z-html&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-inline z-any z-html&quot;&gt;meta&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-attribute-with-value z-html&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-html&quot;&gt;http-equiv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-html&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-html&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-html&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;onion-location&lt;span class=&quot;z-punctuation z-definition z-string z-end z-html&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-attribute-with-value z-html&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-html&quot;&gt;content&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-html&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-html&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-html&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;http:&#x2F;&#x2F;&amp;lt;onion&amp;gt;.onion&lt;span class=&quot;z-punctuation z-definition z-string z-end z-html&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-end z-html&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;automatizacion-del-despliegue&quot;&gt;Automatización del despliegue&lt;&#x2F;h2&gt;
&lt;p&gt;Script único para clearnet + Tor:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;!&#x2F;bin&#x2F;sh&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-set z-shell&quot;&gt;set&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;-&lt;&#x2F;span&gt;e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-assignment z-shell&quot;&gt;ONION_URL&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-shell&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;http:&#x2F;&#x2F;&amp;lt;onion&amp;gt;.onion&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; pull&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;zola&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;doas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; rsync&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;delete&lt;&#x2F;span&gt; public&#x2F; &#x2F;var&#x2F;www&#x2F;htdocs&#x2F;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;zola&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;base-url&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;ONION_URL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;doas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; rsync&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;delete&lt;&#x2F;span&gt; public&#x2F; &#x2F;var&#x2F;www&#x2F;tor&#x2F;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Instalado en: &lt;code&gt;&#x2F;usr&#x2F;local&#x2F;bin&#x2F;update-site&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;control-de-acceso-ssh-yubikey&quot;&gt;Control de acceso: SSH + YubiKey&lt;&#x2F;h2&gt;
&lt;p&gt;Acceso remoto sin contraseñas persistentes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Clave OpenPGP en YubiKey&lt;&#x2F;li&gt;
&lt;li&gt;PIN + touch físico&lt;&#x2F;li&gt;
&lt;li&gt;gpg-agent como SSH agent&lt;&#x2F;li&gt;
&lt;li&gt;ssh-ed25519&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;La clave privada nunca toca el disco.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;control-de-versiones-y-firmas&quot;&gt;Control de versiones y firmas&lt;&#x2F;h2&gt;
&lt;p&gt;Repositorio alojado en GitHub:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Git puro&lt;&#x2F;li&gt;
&lt;li&gt;Commits firmados&lt;&#x2F;li&gt;
&lt;li&gt;Modelo de confianza por defecto&lt;&#x2F;li&gt;
&lt;li&gt;Sin CI obligatorio&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;El servidor no compila desde hooks remotos: el despliegue es consciente y manual.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;estructura-del-proyecto&quot;&gt;Estructura del proyecto&lt;&#x2F;h2&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;site&#x2F;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── config.toml
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── content&#x2F;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── templates&#x2F;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── static&#x2F;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── public&#x2F;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;└── scripts&#x2F;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;En servidor:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&#x2F;var&#x2F;www&#x2F;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── htdocs&#x2F;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── tor&#x2F;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;└── acme&#x2F;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;que-falta-por-hacer&quot;&gt;Qué falta por hacer&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Pendientes reales:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Hardening adicional de httpd&lt;&#x2F;li&gt;
&lt;li&gt;Documentar bootstrap completo desde cero&lt;&#x2F;li&gt;
&lt;li&gt;Monitoreo mínimo (sin agentes invasivos)&lt;&#x2F;li&gt;
&lt;li&gt;Publicar configs como referencia reproducible&lt;&#x2F;li&gt;
&lt;li&gt;Auditoría de headers de seguridad&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;idea-central&quot;&gt;Idea central&lt;&#x2F;h2&gt;
&lt;p&gt;Este proyecto no busca conveniencia ni velocidad de desarrollo.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Busca:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Comprensión&lt;&#x2F;li&gt;
&lt;li&gt;Control&lt;&#x2F;li&gt;
&lt;li&gt;Auditabilidad&lt;&#x2F;li&gt;
&lt;li&gt;Reducción de estados implícitos&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;OpenBSD no acelera el trabajo. Elimina errores silenciosos. Ese es el valor.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>Detección de inundaciones</title>
        <published>2025-11-02T00:00:00+00:00</published>
        <updated>2025-11-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            B.E. Alejandro
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://nezzontli.xyz/es/blog/proyecto1/"/>
        <id>https://nezzontli.xyz/es/blog/proyecto1/</id>
        
        <content type="html" xml:base="https://nezzontli.xyz/es/blog/proyecto1/">&lt;h2 id=&quot;introduccion-y-justificacion&quot;&gt;Introducción y Justificación&lt;&#x2F;h2&gt;
&lt;p&gt;El estado de &lt;strong&gt;Hidalgo&lt;&#x2F;strong&gt; enfrenta una problemática crítica y recurrente de riesgo hídrico, manifestada en inundaciones por desbordamiento de ríos y presas. Esta situación se agrava por la falta de sistemas de monitoreo constante y la ausencia de un &lt;strong&gt;Sistema de Alerta Temprana (SAT)&lt;&#x2F;strong&gt; robusto y accesible para la población en las zonas de riesgo.&lt;&#x2F;p&gt;
&lt;p&gt;Cada temporada de lluvias intensas, miles de familias mexicanas, particularmente en Hidalgo, son afectadas por estos desbordamientos, resultando en la pérdida de vidas y bienes materiales. Un ejemplo trágico y emblemático fue la &lt;strong&gt;inundación del río Tula en septiembre de 2021&lt;&#x2F;strong&gt;, donde el desbordamiento alcanzó hasta &lt;strong&gt;dos metros de altura&lt;&#x2F;strong&gt;, afectando a más de &lt;strong&gt;2,500 viviendas&lt;&#x2F;strong&gt; y cobrando la vida de &lt;strong&gt;17 personas&lt;&#x2F;strong&gt; en el Hospital General de Zona (HGZ) No. 5 del IMSS en Tula de Allende &lt;a href=&quot;https:&#x2F;&#x2F;corrientealterna.unam.mx&#x2F;cronica&#x2F;a-un-ano-de-la-inundacion-en-tula-las-damnificadas-enfrentan-danos-emocionales-y-falta-de-apoyo&#x2F;&quot;&gt;1&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;www.uaeh.edu.mx&#x2F;gaceta&#x2F;3&#x2F;numero32&#x2F;octubre&#x2F;inundaciones-valle-mezquital.html&quot;&gt;2&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Los municipios identificados con mayor vulnerabilidad a este tipo de fenómenos incluyen &lt;strong&gt;Tula de Allende&lt;&#x2F;strong&gt;, &lt;strong&gt;Huehuetla&lt;&#x2F;strong&gt;, &lt;strong&gt;Tianguistengo&lt;&#x2F;strong&gt;, y otras zonas de la Huasteca y la Sierra Hidalguense &lt;a href=&quot;https:&#x2F;&#x2F;www.milenio.com&#x2F;politica&#x2F;comunidad&#x2F;temporada-de-lluvias-en-hidalgo-2025-municipios-riesgo-inundacion&quot;&gt;3&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;www.jornada.com.mx&#x2F;noticia&#x2F;2025&#x2F;10&#x2F;10&#x2F;estados&#x2F;lluvias-desbordan-rios-en-hidalgo-causando-graves-inundaciones-en-7-municipios&quot;&gt;4&lt;&#x2F;a&gt;. Además, la gestión de embalses como la &lt;strong&gt;Presa La Esperanza&lt;&#x2F;strong&gt; (que ha alcanzado el 100% de su capacidad) y la &lt;strong&gt;Presa Tejocotal&lt;&#x2F;strong&gt; (con riesgo de desbordamiento en temporadas de alta precipitación) subraya la necesidad urgente de un monitoreo en tiempo real &lt;a href=&quot;https:&#x2F;&#x2F;es-us.noticias.yahoo.com&#x2F;hidalgo-mantiene-alerta-intensas-lluvias-134942535.html&quot;&gt;5&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;propuesta-de-solucion-sistema-de-deteccion-de-inundaciones-basado-en-meshtastic-lora&quot;&gt;Propuesta de Solución: Sistema de Detección de Inundaciones Basado en Meshtastic&#x2F;LoRa&lt;&#x2F;h2&gt;
&lt;p&gt;Se propone la implementación de un &lt;strong&gt;Sistema de Detección y Alerta Temprana de Inundaciones (SAT-I)&lt;&#x2F;strong&gt; utilizando la tecnología de red mallada &lt;strong&gt;Meshtastic&lt;&#x2F;strong&gt; sobre la infraestructura de radio de largo alcance y baja potencia (&lt;strong&gt;LoRa&lt;&#x2F;strong&gt;). Este sistema está diseñado para operar de manera autónoma y resiliente, incluso ante la caída de las redes de comunicación convencionales (telefonía móvil o Wi-Fi) &lt;a href=&quot;https:&#x2F;&#x2F;www.zonaindustrial.cl&#x2F;meshtastic&quot;&gt;6&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;componentes-y-funcionamiento&quot;&gt;Componentes y Funcionamiento&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Detección de Nivel de Agua:&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;Se emplearán &lt;strong&gt;sensores ultrasónicosicos de grado industrial&lt;&#x2F;strong&gt; con una precisión de hasta &lt;strong&gt;±1 cm&lt;&#x2F;strong&gt; para la medición constante del nivel del agua en ríos o presas.&lt;&#x2F;li&gt;
&lt;li&gt;Estos sensores se integrarán en una &lt;strong&gt;cápsula hermética&lt;&#x2F;strong&gt; de protección, asegurando su resistencia a la corrosión y a las condiciones ambientales extremas.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;strong&gt;Comunicación Autónoma (Meshtastic&#x2F;LoRa):&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;Los datos de los sensores serán transmitidos a través de módulos &lt;strong&gt;LoRa&lt;&#x2F;strong&gt; que ejecutan el &lt;em&gt;firmware&lt;&#x2F;em&gt; &lt;strong&gt;Meshtastic&lt;&#x2F;strong&gt;. Esta tecnología utiliza ondas de radio de largo alcance y bajo consumo, permitiendo la comunicación &lt;em&gt;off-grid&lt;&#x2F;em&gt; (fuera de la red eléctrica o de telecomunicaciones) a distancias de varios kilómetros.&lt;&#x2F;li&gt;
&lt;li&gt;La naturaleza de &lt;strong&gt;red mallada (mesh)&lt;&#x2F;strong&gt; de Meshtastic permite que cada nodo actúe como repetidor, extendiendo el alcance y la redundancia del sistema. En caso de que un nodo falle, la información puede ser retransmitida por otros nodos en la red.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;&lt;strong&gt;Alerta Temprana y Aplicaciones Adicionales:&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;ul&gt;
&lt;li&gt;El sistema no solo detectará desbordamientos inminentes, sino que también puede ser adaptado para &lt;strong&gt;detectar sequías&lt;&#x2F;strong&gt; mediante el monitoreo de niveles mínimos, facilitando la gestión hídrica en presas o zonas rurales.&lt;&#x2F;li&gt;
&lt;li&gt;La alerta se puede emitir a dispositivos portátiles (como &lt;em&gt;smartphones&lt;&#x2F;em&gt; con la aplicación Meshtastic) o a sistemas de alarma locales, garantizando una &lt;strong&gt;evacuación temprana&lt;&#x2F;strong&gt; de la población.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;requerimientos-minimos-para-el-prototipo&quot;&gt;Requerimientos Mínimos para el Prototipo&lt;&#x2F;h3&gt;
&lt;p&gt;Para la implementación inicial de un nodo de monitoreo y su repetidor se requiere:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;Componente&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Cantidad&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Función&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Módulos LoRa&#x2F;Meshtastic&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Nodos de comunicación autónoma (uno para el sensor, otro como receptor&#x2F;gateway).&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Sensores Ultrasónicos&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;2&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Medición precisa (±1 cm) del nivel del agua.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Retransmisor Autónomo&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;1&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Nodo adicional con alimentación solar para extender el alcance de la red mallada.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;consideraciones-de-despliegue&quot;&gt;Consideraciones de Despliegue&lt;&#x2F;h3&gt;
&lt;p&gt;El despliegue del sistema debe ir precedido por un &lt;strong&gt;estudio topográfico&lt;&#x2F;strong&gt; detallado. Este estudio es crucial para:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Determinar la ubicación óptima de los nodos y retransmisores para maximizar el alcance de la red LoRa.&lt;&#x2F;li&gt;
&lt;li&gt;Establecer los umbrales de alerta basados en la topografía de la zona y los niveles históricos de desbordamiento.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Todos los retransmisores deben ser &lt;strong&gt;autónomos&lt;&#x2F;strong&gt; y alimentados por &lt;strong&gt;paneles solares&lt;&#x2F;strong&gt;, aprovechando la eficiencia energética y el bajo consumo de la tecnología LoRa.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;escalabilidad-y-aplicaciones-adicionales-beneficios-para-la-agricultura&quot;&gt;Escalabilidad y Aplicaciones Adicionales: Beneficios para la Agricultura&lt;&#x2F;h2&gt;
&lt;p&gt;La arquitectura modular y resiliente del sistema SAT-I basado en Meshtastic&#x2F;LoRa permite una escalabilidad inmediata para integrar otros sensores y fuentes de datos, ampliando su utilidad más allá de la prevención de inundaciones. Dado que &lt;strong&gt;Hidalgo es un estado con una importante vocación agrícola&lt;&#x2F;strong&gt;, esta escalabilidad ofrece beneficios directos para el sector primario.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;integracion-de-sistemas-meteorologicos-para-prediccion-de-lluvias&quot;&gt;Integración de Sistemas Meteorológicos para Predicción de Lluvias&lt;&#x2F;h3&gt;
&lt;p&gt;Se propone la integración de &lt;strong&gt;estaciones meteorológicas autónomas&lt;&#x2F;strong&gt; (alimentadas por energía solar y equipadas con sensores de precipitación, temperatura y humedad) que también utilicen la red Meshtastic&#x2F;LoRa para la transmisión de datos.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;Dato Adicional&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Beneficio para la Prevención de Inundaciones&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Beneficio para la Agricultura&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Precipitación Acumulada&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Permite modelar la saturación del suelo y predecir el caudal de los ríos con mayor precisión, mejorando la anticipación de la alerta.&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Ayuda a los agricultores a optimizar el riego y a planificar la siembra y cosecha en función de la disponibilidad hídrica.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Temperatura y Humedad&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Ofrece contexto para la predicción de tormentas intensas y fenómenos hidrometeorológicos.&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Facilita la gestión de plagas y enfermedades, y optimiza las condiciones de cultivo para especies específicas.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Al enviar estos datos a través de la red mesh, se crea un sistema de información ambiental &lt;strong&gt;descentralizado y robusto&lt;&#x2F;strong&gt;. La combinación de la &lt;strong&gt;predicción meteorológica&lt;&#x2F;strong&gt; (datos de lluvia) con el &lt;strong&gt;monitoreo hidrológico en tiempo real&lt;&#x2F;strong&gt; (nivel de agua) proporciona una herramienta de análisis mucho más completa para la prevención de desastres.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusión&lt;&#x2F;h2&gt;
&lt;p&gt;La integración de sensores de precisión con la red de comunicación resiliente Meshtastic&#x2F;LoRa ofrece una solución &lt;strong&gt;autónoma y autosuficiente&lt;&#x2F;strong&gt; para la detección temprana de riesgos hídricos en Hidalgo. Este enfoque no solo aborda la vulnerabilidad de las redes convencionales, sino que proporciona una herramienta vital para la &lt;strong&gt;salvaguarda de la población&lt;&#x2F;strong&gt; y la protección de sus bienes ante un desbordamiento inminente.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;referencias-bibliografia&quot;&gt;Referencias (Bibliografía)&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;corrientealterna.unam.mx&#x2F;cronica&#x2F;a-un-ano-de-la-inundacion-en-tula-las-damnificadas-enfrentan-danos-emocionales-y-falta-de-apoyo&#x2F;&quot;&gt;Redacción. (2022, 7 septiembre). &lt;em&gt;A un año de la inundación en Tula: las damnificadas enfrentan daños emocionales y falta de apoyo&lt;&#x2F;em&gt;. Corriente Alterna UNAM.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.uaeh.edu.mx&#x2F;gaceta&#x2F;3&#x2F;numero32&#x2F;octubre&#x2F;inundaciones-valle-mezquital.html&quot;&gt;Gaceta UAEH. (s.f.). &lt;em&gt;Inundaciones en el Valle del Mezquital, una tragedia anunciada&lt;&#x2F;em&gt;. Universidad Autónoma del Estado de Hidalgo.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.milenio.com&#x2F;politica&#x2F;comunidad&#x2F;temporada-de-lluvias-en-hidalgo-2025-municipios-riesgo-inundacion&quot;&gt;Milenio Digital. (2025, 12 mayo). &lt;em&gt;Estos son los municipios de Hidalgo con mayor riesgo de inundaciones&lt;&#x2F;em&gt;. Milenio.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.jornada.com.mx&#x2F;noticia&#x2F;2025&#x2F;10&#x2F;10&#x2F;estados&#x2F;lluvias-desbordan-rios-en-hidalgo-causando-graves-inundaciones-en-7-municipios&quot;&gt;La Jornada. (2025, 10 octubre). &lt;em&gt;Lluvias desbordan ríos en Hidalgo causando graves inundaciones en 7 municipios&lt;&#x2F;em&gt;.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;es-us.noticias.yahoo.com&#x2F;hidalgo-mantiene-alerta-intensas-lluvias-134942535.html&quot;&gt;Yahoo Noticias. (2025, 30 junio). &lt;em&gt;Hidalgo se mantiene en alerta por intensas lluvias y presas al límite&lt;&#x2F;em&gt;.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.zonaindustrial.cl&#x2F;meshtastic&quot;&gt;Zona Industrial. (s.f.). &lt;em&gt;Meshtastic - Guía para tu Red Mesh&lt;&#x2F;em&gt;.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;-&#x2F;es&#x2F;YoLink-LoRa-inteligente-inundaciones-notificaciones&#x2F;dp&#x2F;B083Z5Z9HM&quot;&gt;YoLink. (s.f.). &lt;em&gt;YoLink LoRa - Sensor de fugas de agua de hasta 1&#x2F;4 de milla&lt;&#x2F;em&gt;.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
</feed>
