El problema de llegar a Home Assistant desde fuera

Aquí Home Assistant lleva la casa: las luces, la calefacción, el aire acondicionado, el cargador del coche, las alarmas. La app del móvil es como se usa todo eso fuera de casa, y también es como la casa sabe dónde están los móviles, porque la app informa de la ubicación y de los sensores en segundo plano.

Así que tiene que funcionar cuando no hay nadie en casa. La pregunta es cómo.

La respuesta habitual es poner Home Assistant en internet con un nombre de host y una página de inicio de sesión. Funciona. También significa que cualquiera del planeta puede llegar a la página de inicio de sesión, probar contraseñas contra ella y husmear lo que haya detrás. Una página de inicio de sesión es una contraseña entre internet y las cerraduras de tu puerta.

Yo no quería eso. Los requisitos eran pocos:

  • Ninguna página de inicio de sesión accesible al público. No responde nada salvo que el dispositivo sea de los nuestros.
  • La app de Home Assistant tiene que seguir funcionando en segundo plano, sin nadie pasando por un inicio de sesión.
  • Nada extra funcionando en los móviles. Ningún agente VPN.
  • El plan gratuito de Cloudflare. El túnel ya está ahí.

Esos cuatro descartan la mayoría de las opciones habituales antes de empezar.

Lo que te da de verdad cada opción

La propia documentación de Home Assistant lista las vías de entrada: Home Assistant Cloud, una VPN, un proxy inverso o la redirección de puertos1. Cloudflare añade sus propias versiones de las dos últimas. Así puntúan contra esos cuatro requisitos, qué puede salir mal con cada una, y cuánto cuesta cada una en batería.

OpciónQuién llega a la página de inicio de sesiónLa app funciona en segundo planoExtra en el móvilLo que cuesta de verdadRiesgosCoste de bateríaIPv4 e IPv6
Redirección de puerto a Home AssistantTodo el mundoSíNadaGratis en la factura. Cada escaneo y cada intento de contraseña corre en Home Assistant, y un DDoS cae en tu línea de casaPágina de inicio de sesión abierta a todo escáner. Un agujero en el router directo a la LAN. Una línea de casa detrás de CGNAT no tiene puerto que redirigir2. App: funciona en Android y iPhone, es solo una URLNormalIPv4 necesita una dirección pública propia, no CGNAT. IPv6 necesita abrir un hueco en el cortafuegos, y un móvil en una Wi-Fi solo IPv4 no llega
Cloudflare Tunnel, nada másTodo el mundoSíNadaGratis. Cloudflare se come un DDoS, pero cada intento de contraseña sigue corriendo en Home AssistantPágina de inicio de sesión abierta a todo escáner y toda lista de contraseñas. Una contraseña adivinada y el atacante tiene una máquina en tu LAN. App: funciona en Android y iPhone, es solo una URLNormalLas dos. Cloudflare responde por cualquiera3, y la casa solo llama hacia fuera4
Túnel más un inicio de sesión de Cloudflare AccessSolo tras iniciar sesiónNo, las llamadas en segundo plano chocan con el inicio de sesiónNadaGratis. Los desconocidos se quedan en Cloudflare, sin carga en Home AssistantLa ubicación y los sensores dejan de informar sin que nadie se dé cuenta. Solo se publica Home Assistant, detrás del inicio de sesión. App: no puede mandar la cabecera de service token que necesita Access5NormalLas dos, igual que el túnel
Túnel más red privada WARPNadie de fueraSíAgente WARPGratis. Nada público que escanearFunciona en puertos UDP que la red de un hotel o una oficina puede bloquear6. Android permite una VPN a la vez7. Una ruta puede poner toda la LAN en cada móvil inscrito8. App: no necesita nada, pero WARP tiene clientes para Android e iPhone y ninguno para un reloj Wear OS9Mayor, una VPN siempre activaLas dos. El agente llega a Cloudflare por cualquiera6
Home Assistant CloudTodo el que tenga la URLSíNada6,50 £ al mes o 65 £ al año10. Los intentos de contraseña siguen corriendo en Home AssistantPágina de inicio de sesión pública. La entrada la tiene la empresa de otro: sin entrada cuando su servicio está caído. Una contraseña adivinada y el atacante tiene una máquina en tu LAN. App: funciona en Android y iPhoneNormalEn casa cualquiera, llama hacia fuera a un relé de Nabu Casa11. IPv6 para el móvil no está documentado
Redirección de puerto a nginx o Caddy con certificado de clienteSolo dispositivos con certificadoSíUn certificado y la raíz de tu propia CAGratis en la factura. Un desconocido cuesta un saludo TLS en el proxy, nunca un inicio de sesión de Home Assistant, y un DDoS cae en tu línea de casaUn agujero en el router hacia el proxy, no hacia Home Assistant. Llevas tú la CA, y una CRL vieja deja fuera a todos los móviles. App: como la fila del certificado de abajoNormalComo la redirección de puerto. A nginx hay que decirle que escuche en IPv6, Caddy lo hace por defecto
Túnel más certificado de clienteSolo dispositivos con certificadoSíUn certificadoGratis. Los desconocidos se rechazan en el borde, sin carga en Home AssistantUn móvil perdido entra hasta que se revoca. HTTPS normal en el 443, bloqueado solo donde lo esté la web. Solo se publica Home Assistant, y solo para quien tenga certificado. App: soportado en Android; la app de iPhone no está documentada; Wear OS necesita el archivo PKCS12 durante la configuración12NormalLas dos, igual que el túnel

El túnel también quita de en medio la cuestión de IPv4 contra IPv6. Cloudflare responde al móvil por la que tenga, y la casa solo llama hacia fuera, así que una línea de casa detrás de CGNAT, o una con IPv6 y sin ninguna IPv4 pública, funciona igual que cualquier otra. Una redirección de puerto necesita una dirección IPv4 pública propia, o IPv6 en los dos extremos. Por qué tantas líneas de casa siguen sin tener ninguna de las dos es otra historia, en Nunca nos quedamos sin direcciones. Nos quedamos sin ganas..

El túnel por sí solo arregla el router, no la exposición. cloudflared hace conexiones solo salientes, así que no hay puerto entrante que redirigir13, pero el nombre de host que publica sigue sirviendo la página de inicio de sesión a cualquiera que la pida.

¿Lo arregla Cloudflare Access? Para un navegador, sí, y así lo usan los escritorios de VDI Zero Trust sin la factura de la nube. Para la app tiene la forma equivocada. Access pone a una persona delante de una página de inicio de sesión, y el tráfico en segundo plano de la app no tiene persona. El apaño habitual es un service token mandado como cabecera, y la app no puede mandarlo. Su vista web no da forma de añadir cabeceras a las peticiones POST ni a los WebSockets, que es como habla la app con Home Assistant, y la discusión de los desarrolladores acaba en los certificados de cliente como «a better (more secure) alternative»5.

WARP lo haría, y se descartó porque significa un agente en cada móvil. Una VPN gasta más batería que un enlace normal, porque es un túnel abierto todo el día, hable la app o no. Funciona sobre UDP en puertos que la red de un hotel o de una oficina puede tirar, lo que te deja fuera justo cuando estás fuera6. Y Android lleva una VPN a la vez7, así que WARP y una VPN del trabajo no pueden estar las dos arriba. Home Assistant Cloud es un buen servicio y paga el desarrollo, pero es una suscripción, y la URL sigue sirviendo una página de inicio de sesión a quien la encuentre. Además le da la entrada de tu casa a la empresa de otro. Su servicio, su cuenta, su precio, sus condiciones. Eso es una pérdida de soberanía, y es el trato que te pide toda oferta en la nube: comodidad ahora, otro al mando para siempre.

Cloudflare no es distinto en esencia, y sería deshonesto fingir lo contrario. Todas las opciones de túnel de esta tabla lo ponen en el camino, y termina el TLS en su borde, que es como la regla WAF llega a leer la comprobación del certificado. La diferencia es cuánto guarda. Aquí guarda la puerta. Home Assistant, sus datos y sus contraseñas se quedan en casa, y si Cloudflare desaparece la casa sigue funcionando, que es la última fila de la tabla de «Dónde se queda corto». Si incluso eso es más confianza de la que quieres ceder, la versión con nginx y Caddy hace la misma comprobación en tu propia casa, con tu propia CA, y a cambio asume la redirección de puerto y las tareas de la CA.

Eso deja el certificado de cliente. El móvil demuestra lo que es antes de que Home Assistant vea un solo byte.

Lo que cuesta de verdad estar abierto a internet

Gratis en la factura no es lo mismo que gratis. Todo lo que responde a internet lo paga en carga de la máquina. Cada intento de contraseña contra el propio inicio de sesión de Home Assistant es una comprobación bcrypt de 12 rondas, y la hace aunque el usuario no exista, así que un desconocido adivinando cuesta exactamente lo mismo que cuando entras tú14. Esa carga cae en la máquina que lleva la casa, día y noche, mientras sigan llegando los escáneres. Y siguen llegando.

Una redirección de puerto es peor todavía, porque pone en juego la dirección de tu casa. Un DDoS dirigido a ella llena tu banda ancha, y entonces toda la casa se queda sin internet, no solo Home Assistant. Detrás del túnel Cloudflare se come la inundación, en todos los planes incluido el gratuito15, y no ha echado a ningún cliente por el tamaño de un ataque desde 201716. El certificado da el último paso. Un desconocido se rechaza en el borde, y Home Assistant no gasta nada en él.

Luego está la red en la que vive Home Assistant. No es una app web en una isla. Está en la LAN de casa al lado de las cámaras, el NAS y los portátiles, y guarda las credenciales de bastantes de ellos. Pasa su inicio de sesión y tienes una máquina dentro de la casa, no solo un panel. Una redirección de puerto es un agujero en el router que apunta directamente a esa máquina. WARP se equivoca por el otro lado, por ser demasiado generoso: una ruta puede publicar una red privada entera a cada móvil inscrito, y acotarla es una política aparte que tienes que acordarte de escribir8. Pierde un móvil con eso puesto y quien lo encuentre está en tu LAN. El certificado publica un nombre de host, a los dispositivos que tienen uno, y nada más de la red es alcanzable desde fuera.

mTLS en el plan gratuito: qué mitad es gratis

Buena parte de los consejos que hay por internet dicen que mTLS en Cloudflare necesita Enterprise. No es así. Cloudflare vende mTLS dos veces, y solo una de ellas necesita Enterprise.

Certificados de cliente más regla WAFmTLS de Cloudflare Access
PlanFree, Pro, Business, EnterpriseSolo Zero Trust Enterprise
Autoridad de certificaciónGestionada por Cloudflare (traer la tuya es Enterprise)Solo la tuya
Certificados incluidos100 activos por zonaNo aplica
Lo hace cumplirUna regla personalizada del WAF que escribes túUna política de Access
RevocaciónIntegrada, la comprueba la reglaTu propia CRL y un Worker

La primera columna es la que queremos. Traer tu propia CA es Enterprise en Cloudflare. Fuera de Cloudflare no cuesta nada, y certificados de cliente de step-ca lo cubre. La propia comparación de Cloudflare lo dice claramente: la oferta de Application Security incluye 100 certificados de cliente por zona gratis, mientras que mTLS de Access es una función de Zero Trust Enterprise17. Los planes Free, Pro y Business tienen 100 certificados activos por zona, y revocar uno libera su hueco al momento18. Dos móviles usan dos.

El plan gratuito también trae cinco reglas personalizadas del WAF19. Esto necesita una.

Cómo funciona la comprobación

Flujo de peticiones por mTLS de Cloudflare hasta Home AssistantMóvilapp de HAtiene cert.Cualquieraun escánersin certificadoBorde de Cloudflare, plan gratuitoSaludomTLS activo enha.example.compide un cert.Regla WAF¿verificado?¿no revocado?si no, BlockBloqueadonunca llega a HARed de casacloudflaredtúnel solo salienteHome Assistantconfía solo en su proxybloqueo de IP activologin: segundo candadopasafalla
Cada petición: el borde pide un certificado durante el saludo, la regla WAF bloquea todo lo no verificado o revocado, y solo entonces baja la petición por el túnel hasta Home Assistant.

Cloudflare hace el trabajo en su borde. Cuando mTLS está activado para un nombre de host, el saludo TLS le pide un certificado al cliente20. Eso solo no bloquea nada. Un cliente que no manda certificado sigue conectando. Simplemente llega con el campo de verificación a falso.

El bloqueo es la regla WAF. Cloudflare expone el resultado de la comprobación del certificado como campos de su lenguaje de reglas21:

(http.host eq "ha.example.com"
  and (not cf.tls_client_auth.cert_verified
       or cf.tls_client_auth.cert_revoked))
Action: Block

La segunda línea está ahí por algo. Un certificado revocado sigue verificando, porque que cert_revoked sea verdadero significa que cert_verified también lo es22. Comprueba solo el primer campo y un certificado revocado entra como si nada. Revocar el certificado de un móvil perdido no sirve de nada salvo que la regla lo pregunte.

Hay que reconocerlo: la gente del hilo de la app de Android de Home Assistant dio con esta regla y la publicó5. Buen trabajo, y me ahorró un montón de búsqueda.

El lado de Home Assistant

A Home Assistant hay que decirle que está detrás de un proxy, y no es opcional. Las peticiones de un proxy inverso se bloquean por diseño hasta que se le dice a Home Assistant que confíe en él23. El conector cloudflared del túnel cuenta como uno.

Desde la 2026.8 estos ajustes están en la interfaz, en Settings → System → Network → HTTP server, no en configuration.yaml23. Guardarlos reinicia Home Assistant, y un administrador tiene entonces cinco minutos para confirmar los ajustes nuevos antes de que se deshagan solos. Es una red de seguridad que conviene conocer antes de dejarte fuera.

AjusteValorPor qué
Trust X-Forwarded-ForActivadoSin él, las peticiones que pasan por proxy se rechazan
Trusted proxiesSolo la dirección de la máquina de cloudflaredSolo esa máquina puede decir que reenvía en nombre de alguien
Enable IP banningActivado, unos pocos intentosLos bloqueos caen sobre la dirección real del cliente, no sobre la de Cloudflare
Home Assistant URL, Internethttps://ha.example.comLa app la toma como su URL externa

La entrada de proxies de confianza es estrecha a propósito. Confía en una subred entera y cualquier dispositivo de ella puede falsificar la dirección del cliente, lo que deja la lista de bloqueos sin valor.

Luego la app. La documentación de la app Companion cubre esta configuración por su nombre. Si Home Assistant está detrás de un proxy inverso que hace autenticación de cliente TLS, la app pide un certificado, y lo quiere instalado como «VPN & app user certificate»12. En un móvil sin certificado recibes un error o una pantalla en blanco, que es el resultado correcto para un móvil que no debería entrar.

Pon el nivel de seguridad de conexión de la app en Most secure. La dirección local http:// normal solo se usa entonces en la Wi-Fi de casa, y en cualquier otro sitio la app usa el nombre de host HTTPS o se niega a conectar24. Necesita el permiso de ubicación en «Allow all the time» en Android, que la app necesita de todos modos para la ubicación en segundo plano.

Construirlo, paso a paso

PasoDóndeQué
1Túnel de CloudflareAñadir un nombre de host público, ha.example.com, apuntando a Home Assistant en la LAN
2SSL/TLS → Client CertificatesCrear un certificado por móvil. Copiar el certificado y la clave, no se vuelven a mostrar18
3Client Certificates → HostsActivar mTLS para ha
4Security → WAF → Custom rulesAñadir la regla de bloqueo de arriba
5SSL/TLS → Edge CertificatesAlways Use HTTPS activado, TLS 1.2 como mínimo
6Home Assistant → NetworkProxy de confianza, bloqueo de IP, URL externa, y confirmar en menos de cinco minutos
7Una máquina LinuxConstruir un archivo PKCS12 por móvil
8Cada móvilInstalarlo como certificado de usuario de VPN y aplicaciones, y poner la app en Most secure
9PruebaDatos móviles, Wi-Fi apagada. La app conecta. Un navegador sin el certificado queda bloqueado

Un certificado por móvil, no uno compartido. Cuando se pierde un móvil, revocas ese móvil y el otro sigue funcionando.

El móvil quiere el certificado y la clave en un archivo PKCS12. Cloudflare te da PEM, así que únelos:

openssl pkcs12 -export -in phone1.pem -inkey phone1.key \
  -name "ha-phone1" -out phone1.p12

Aquí es donde la gente se atasca. Android es quisquilloso con el cifrado dentro del archivo, y la documentación de Home Assistant dice que pruebes primero el valor por defecto actual y recurras a un contenedor heredado con la opción -legacy de OpenSSL solo si se rechaza25. El mismo consejo sale en los hilos de la comunidad donde un archivo que se instalaba bien en equipos de Apple era rechazado por Android5.

La ruta de menús para instalarlo cambia entre fabricantes de móviles y versiones de Android. La propia página de Google para el Pixel es un punto de partida26. Digan lo que digan los menús, lo que quieres es el almacén de credenciales de usuario, no el de CA.

Dónde se queda corto

Nada de esto está libre de asperezas, así que aquí van.

CasoQué pasaQué hacer
Móvil perdido o vendidoSu certificado sigue funcionando hasta que se revocaRevocarlo en Client Certificates. La regla comprueba la revocación
Reloj Wear OSNo puede usar el certificado instalado en el móvilEntregar el archivo PKCS12 durante la configuración del propio reloj12
iPhoneLa documentación de Companion marca esta sección como solo AndroidProbarlo antes de depender de ello
Navegador del portátil fuera de casaBloqueado, sin certificadoInstalar un certificado en el navegador, o aceptarlo
Cloudflare caídoNingún acceso remotoLa casa sigue funcionando en local. Para eso se lleva en local

Lo del navegador es una función, no un fallo. Todo lo que no tenga certificado es un desconocido, y eso incluye mi propio portátil hasta que le dé uno.

Una llave, no una contraseña

Una contraseña es algo que sabes, y todo lo que sabes se puede adivinar, pescar con phishing, reutilizar o filtrar en la brecha de otro. Pon una página de contraseña en internet y has entrado en un juego de números contra todo el que tenga una botnet y una lista de palabras. Puede que lo ganes durante años. Solo tienes que perder una vez.

Un certificado es algo que tiene el dispositivo. Nadie lo adivina. Nadie lo prueba un millón de veces, porque la petición se tira en el borde antes de que haya nada contra lo que probarlo. La página de inicio de sesión sigue ahí y sigue importando, pero ahora es el segundo candado, no el único.

Lo que hay detrás de esa página no es una app web. Son las cerraduras, la calefacción, el cargador del coche y las cámaras. Trátalo como la puerta de casa, porque eso es lo que es.

Lo que no se me quita de la cabeza es que nada de esto cuesta nada. Cloudflare regala los certificados y la regla en el plan gratuito. Home Assistant documenta el lado de la app en su propia documentación de Companion. Lo único que cuesta es una tarde leyendo bien los manuales, y como tal el valor por defecto de una página de contraseña mirando a todo internet es una elección que la gente hace por no leerlos.


  1. Home Assistant — Remote access — Home Assistant Cloud, VPN, proxy inverso y redirección de puertos como vías de entrada. ↩︎

  2. RFC 6598 — IANA-Reserved IPv4 Prefix for Shared Address Space — el rango 100.64.0.0/10 para Carrier-Grade NAT, donde muchos clientes comparten una dirección pública y ninguno recibe un puerto entrante. ↩︎

  3. Cloudflare — IPv6 compatibility — activado por defecto en todos los planes; Cloudflare «auto generates AAAA DNS records to allow IPv6 clients to connect» a los nombres de host con proxy. ↩︎

  4. Cloudflare — Tunnel run parameters, edge-ip-version — cloudflared se conecta a Cloudflare por IPv4 por defecto; 6 o auto hace que use IPv6. ↩︎

  5. home-assistant/android PR #3593 — Add custom header support — la vista web no puede añadir cabeceras a peticiones POST ni WebSocket; se proponen certificados de cliente en lugar de service tokens; usuarios que informan de problemas de formato de certificado en Android. ↩︎ ↩︎ ↩︎ ↩︎

  6. Cloudflare — Cloudflare One client firewall requirements — WireGuard en UDP 2408 con alternativas en UDP 500, 1701 y 4500; MASQUE en UDP 443. ↩︎ ↩︎ ↩︎

  7. Android Developers — VpnService — «There can be only one VPN connection running at the same time.» ↩︎ ↩︎

  8. Cloudflare — Connect an IP/CIDR — «You can connect an entire private network, a subnet, or an application defined by a static IP»; las políticas de red de Gateway para filtrar ese tráfico son un paso aparte, recomendado. ↩︎ ↩︎

  9. Cloudflare — Download Cloudflare One Client — clientes para Windows, macOS, Linux, iOS 15+, Android 5.0+ y ChromeOS; ningún cliente de Wear OS en la lista. ↩︎

  10. Nabu Casa — Pricing — Home Assistant Cloud a 6,50 £ al mes o 65,00 £ al año, impuestos no incluidos. ↩︎

  11. NabuCasa/hass-nabucasa — remote.py — Home Assistant se registra en Nabu Casa, recibe un server de relé, y se conecta hacia fuera a él. ↩︎

  12. Home Assistant Companion — Getting Started, TLS client authentication — instalar como «VPN & app user certificate»; Wear OS necesita que el certificado se entregue como PKCS12 durante la configuración inicial. ↩︎ ↩︎ ↩︎

  13. Cloudflare — Cloudflare Tunnel — cloudflared crea conexiones solo salientes, así que no hay nada escuchando en el origen. ↩︎

  14. Home Assistant core — auth/providers/homeassistant.py — contraseñas con hash bcrypt de 12 rondas; un usuario desconocido sigue ejecutando un checkpw ficticio «to make timing the same as if user was found». ↩︎

  15. Cloudflare — DDoS Protection — detección y mitigación automática de DDoS, «Available on all plans». ↩︎

  16. Cloudflare blog — Unmetered Mitigation — «Cloudflare will no longer terminate customers, regardless of the size of the DDoS attacks they receive, regardless of the plan level they use.» ↩︎

  17. Cloudflare — Use mTLS with Cloudflare protected resources — «100 Client Certificates per Zone are included for free»; mTLS de Access es una «Zero Trust Enterprise only feature». ↩︎

  18. Cloudflare — Create a client certificate — 100 certificados activos por zona en Free, Pro y Business; revocar libera el hueco; el certificado y la clave no se vuelven a mostrar tras crearlos. ↩︎ ↩︎

  19. Cloudflare — WAF custom rules — tabla de disponibilidad: cinco reglas personalizadas en el plan Free. ↩︎

  20. Cloudflare — Enable mTLS — activar mTLS por nombre de host, y luego hacerlo cumplir con una regla personalizada del WAF. ↩︎

  21. Cloudflare — Client certificate variables — los campos de mTLS disponibles para las reglas personalizadas del WAF. ↩︎

  22. Cloudflare — cf.tls_client_auth.cert_revoked — «When true, the cf.tls_client_auth.cert_verified field is also true.» ↩︎

  23. Home Assistant — HTTP integration — proxies inversos, proxies de confianza y bloqueo de IP; los ajustes pasaron a la interfaz en la 2026.8 y se deshacen salvo que se confirmen en cinco minutos. ↩︎ ↩︎

  24. Home Assistant Companion — Connection security level — Most secure solo usa una URL sin cifrar en la red de casa; necesita la ubicación en «Allow all the time» en Android. ↩︎

  25. Home Assistant Companion — Networking, TLS Client Authentication — prueba primero el PKCS12 por defecto actual, y el contenedor -legacy de OpenSSL solo si eso falla. ↩︎

  26. Google — Pixel Phone Help, Add & remove certificates — instalar un certificado a mano en un Pixel. ↩︎