Acceso seguro a una casa inteligente en ausencia de una IP pública (parte 1)

Introducción


Es difícil elegir un título amplio que refleje el significado, por lo que describiré de inmediato la tarea que me puse.

Hay una "casa inteligente". En mi caso, este es un servidor doméstico sin ventilador con ioBroker, aunque esto no es importante. Además de las cosas del hogar, quiero conectarle sensores desde el exterior (por ejemplo, en un ESP32 desde un invernadero remoto). Decidí hacer esto a través de mqtt. Acceso a la interfaz desde Internet.

Lo de siempre. Pero hay matices:

  • El proveedor no tiene forma de darme una dirección IP pública. Y no hay otros proveedores.
  • No me gusta vincularme a servicios específicos en la nube. También se puede cerrar un servicio externo (ya que gbridge envió una notificación recientemente). Y solo en caso de falla no está claro qué hacer. Prefiero el mío, que se puede transferir, rehacer con poca sangre si sucede algo.
  • La seguridad es importante. No es paranoia, sino poner ioBroker en Internet, especialmente teniendo en cuenta que hay varios servicios exhibidos (flot ...). No realmente.

Además, quiero mostrar no inmediatamente el resultado, sino el proceso. Cómo fue, cómo se transformó la lista de deseos, las decisiones cambiaron. Es posible que algunos puntos se puedan resolver de manera más correcta / eficiente (no soy administrador del sistema, ni desarrollador). O tal vez alguien no llegue tan lejos y aproveche una solución provisional que, por ejemplo, no encontré segura o conveniente para mí. En realidad, lo que se describe en esta parte es una opción bastante funcional, pero para mí es "intermedia".

Dirección pública de mqtt


En casa, la IP pública en el enrutador no brilla (no estoy hablando de fija, esto se puede resolver a través de dyndns y análogos), es decir, el proveedor da 10.x.x.x, sin opciones. Por lo tanto, debe alquilar un VPS pequeño y hacer un probros a través de él.

La forma más fácil es hacer un túnel a través de ssh. En el servidor doméstico (lo llamaré iob.xxx.xx) ejecuto:

ssh -N -T -R pub.xxx.xx:1883:127.0.0.1:1883 a@iob.xxx.xx 

Al conectarse al puerto 1883 del servidor externo pub.xxx.xx, en realidad se encuentra en su iob: 1883 con el contenedor mqtt (mosquito) en funcionamiento.

Naturalmente, es necesario que esto se inicie automáticamente, la conexión se restablece después de una falla. Por lo tanto, usé autossh, diseñándolo como un servicio.

/etc/systemd/system/ssh_mqtt.service:

[Unit]
Description=SSH Tunnel mqtt
After=network.target

[Service]
Environment="AUTOSSH_GATETIME=0"
ExecStart=autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -NR pub.xxx.xx:1883:127.0.0.1:1883 -i /home/a/.ssh/id_rsa a@pub.xxx.xx

[Install]
WantedBy=multi-user.target

Todo tipo de systemctl habilitar / reiniciar, etc. No lo describiré.

Desafortunadamente, a pesar de autossh, me persiguieron las heladas constantes. Así que decidí que no era necesario producir entidades y decidí usar el ssh habitual:

/etc/systemd/system/ssh_mqtt.service:

[Unit]
Description=SSH Tunnel mqtt
After=network.target

[Service]
Restart=always
RestartSec=20
User=anri
ExecStart=/bin/ssh -N -T -R pub.xxx.xx:1883:127.0.0.1:1883 -i /home/a/.ssh/id_rsa a@pub.xxx.xx

[Install]
WantedBy=multi-user.target

Posteriormente, por cierto, resultó que este proveedor es tan oblicuo. Bueno, o la tarifa más barata para 45 rublos / mes, por lo que le funciona torcidamente. La sesión se cuelga periódicamente, incluso cuando simplemente se conecta a través de ssh (MobaXterm). Así que al final me ordené un VPS de otro (55 rublos / mes), y los problemas con las heladas desaparecieron.

Por cierto, elegí por mí mismo dónde tomar VPS no solo en función del precio, sino también teniendo en cuenta el ping (10-20 ms).

En general, esta opción es bastante normal, especialmente teniendo en cuenta que posteriormente hice una conexión a Internet exclusivamente al puerto 8883 a través de TLS. Aquellos. La contraseña para mosquitto se transmitió encriptada.

Posteriormente, los certificados de cliente son obligatorios. Aquellos. primero, en el nivel TLS, debe presentar un certificado de cliente y luego iniciar sesión con el nombre de contraseña especificado en mosquito. Aquellos. No es tan fácil llegar a la fase de búsqueda de contraseña.
En consecuencia, al principio usé el certificado de servidor de LetsEncrypt, luego, debido a la necesidad de certificados de cliente, cambié a la firma automática.

Como en el proceso también trabajé en el software para ESP32, noté (o simplemente pensé, ya no lo recuerdo) que con problemas con una conexión VPN, la batería se consumirá mucho más rápido. Durante el funcionamiento normal, el ciclo: Despierte, aplique energía a los sensores, conéctese a WiFi, establezca una conexión con el servidor mqtt, lea las lecturas del sensor cuando estén listas, transfiéralas a mqtt, apague la alimentación de los sensores, duerma profundamente durante 10 minutos.

Normalmente, dicho ciclo dura aproximadamente 4 segundos. 1.5-2 segundos: conexión a WiFi, un segundo adicional debido a la transición a mqtt a través de TLS. Te queda bien durante 4 segundos, de todos modos, los sensores necesitan tiempo para despertarse. Pero si la VPN se cayó (era claramente visible cuando se caía autossh), ¿qué debo hacer? Por supuesto, lo configuré para que después de 20 segundos el sistema se durmiera de todos modos. Pero 20 segundos en lugar de 4 es muy notable.

En general, decidí que es mejor mantener el servidor mqtt en un VPS externo. Ahora que todo funciona como un reloj, no estoy seguro de si esto es necesario. Pero no veo ningún sentido en rehacerlo.

Dirección pública para Vis


Vis es un sistema de visualización popular en ioBroker. No podría molestarse, configúrelo usted mismo en https y del mismo modo solo envíe el puerto. Además, puede solicitar una contraseña a nivel de aplicación.

Pero eso no es genial. Especialmente teniendo en cuenta que para el trabajo conecta servicios adicionales. Digamos, dibujo gráficos en flot, relativamente hablando, me conecto a vis.xxx.xx : 8082 / vis / index.html, pero dentro hay enlaces a gráficos vis.xxx.xxx : 8082 / flot / index.html. En algún momento, resultó que cuando se conecta a / vis, se solicita una contraseña y se puede acceder a la interfaz gráfica sin una contraseña.

En algunos momentos, en general, era extraño: me autorizaron el vis, veo el gráfico, pero en la parte inferior derecha hay una ventana translúcida "Sin conexión al servidor". Reescribió este bloque css para ocultarlo. Pero, tan pronto como comencé a usar el marco para cambiar entre gráficos en la misma pantalla, resultó que mi superposición en la pantalla en el marco no funcionaba. (Como resultó más tarde, debería ser así). Apago la autorización: todo está bien, no hay que decir malas palabras.

Así que decidí usar el mismo servidor externo para generar nginx en modo proxy inverso. Y ya lo autorizo.

Desde el navegador funcionó. Pero la aplicación nativa iobroker.vis del Play Market no pudo iniciar sesión de esta manera. Y quería usarlo. Aunque esto es en realidad un navegador en la ventana, pero tiene una serie de características agradables. Digamos que establece la escala (93% en modo vertical) y la imagen se ajusta. En otro dispositivo con una resolución de pantalla diferente, simplemente selecciona el coeficiente, y eso es todo. Y en el navegador debes ajustar cada vez ...

Bien, creo. Agregaré un código complicado en la URL en lugar de la contraseña. Escriba vis.xxx.xx : 8082 / <secuencia larga> /vis/index.html. A menudo se usa tal truco.

Casi ganado. Pero con problemas técnicos, la excavación mostró que esta aplicación web no estaba escrita correctamente. Muchos enlaces en su interior no son relativos, sino desde la raíz.

De acuerdo, encontré varios enlaces, escribí para ellos, dicen, si el referente contiene dicho código, aún confía, reescribe la URL, etc. Pero gradualmente salieron a la luz. Así que decidí que esto es torcido, incorrecto, y que se necesita un enfoque diferente.

VPN


Decidí sacrificar un poco la universalidad de acceso. Permítame tener acceso desde mi computadora portátil, teléfono inteligente. Pero desde los dispositivos de otras personas, desde el cibercafé no es necesario, me las arreglaré. Luego puede poner un pequeño cliente que instalará la VPN. Y en su interior, no se requiere SSL ni autorización. Y al mismo tiempo, no necesita rehacer los enlaces.

La forma más simple para mí fue Zerotier. Para mi sistema operativo (Windows, Android, Linux) hay clientes. E incluso hay algunos confeccionados en la ventana acoplable. Si. Ejecuto todo en Docker, sobre las características de esto más adelante.

Instalas el cliente, ingresas un código único para tu red, luego lo confirmas en la interfaz web en my.zerotier.com , si es necesario, configura una dirección estática desde tu red privada personal (a la 10.20.30.0), y eso es todo. Todos los clientes conectados se ven entre sí.

Lo único con lo que tuve que lidiar un poco fue "cómo conectarse a un servidor remoto desde un dispositivo en el WiFi de su hogar sin iniciar el cliente". Bueno, mi servidor doméstico ya es un cliente, incluso si se enruta solo. Resultó que todo es simple. La red doméstica 192.168.x.0 debe registrarse en my.zerotier.com en la sección Rutas administradas, especificando como mi puerta de enlace, por supuesto, este es mi servidor doméstico. Bueno, en la red WiFi, configure la ruta en consecuencia (en el enrutador WiFi, estadísticas 10.20.30.0 en el servidor doméstico).

Al conectar un cliente Zerotier, puede especificar un servidor DNS diferente. Aquellos. Conecté el cliente, y el nombre de dominio no se resuelve en una dirección pública, sino en una privada, porque DNS ahora apunta al servidor doméstico, donde dnsmasq obtiene los registros IP individuales de la red privada Zerotier.

Incluso Zerotier está satisfecho con la elección efectiva de una ruta para la conexión. Si activo un cliente Zerotier en el WiFi de la casa, hacer ping a la computadora de la casa (su dirección IP emitida por Zerotier) es el mismo par de milisegundos que sin un cliente (solo a través de WiFi). Aquellos. La conexión a la nube es solo en el primer momento. El intercambio de tráfico adicional se lleva a cabo directamente, no a través de la nube. Si instala, por ejemplo, OpenVPN en VPS, el mismo tráfico se ejecutó desde el cliente a VPS, y luego regresó a la misma red WiFi al servidor doméstico.

En principio, incluso hay un chip para poner sus servidores lunares. Casi en una red aislada de Internet, toda esta economía debe desplegarse.

Cual es el resultado?


ESP32 envía sus datos al servidor mqtt implementado en el VPS. Sobre TLS, se requiere certificado de cliente.

Se instala una VPN a través de Zerotier con el servidor doméstico. Sonoff rfBridge se comunica con el firmware de Tasmota a través de este servidor doméstico desde mqtt a VPS. No hay forma de configurar TLS con un certificado de cliente, por lo que el MQTT habitual está configurado para 1883. De todos modos, después de todo, el servidor doméstico cifrará este tráfico usando Zerotier.

Bueno, me conecto a vis desde la red doméstica directamente y desde Internet activando el cliente Zerotier. No puede apagarlo en absoluto, esto también funciona. Pero solo a veces necesito otros clientes VPN (por ejemplo, vaya a "Prohibido por ILV"). Dos VPN en un teléfono inteligente no se hicieron amigos de inmediato, pero no lo entendí.

Todo es muy simple. Pero el gusano se tragó el alma. Aunque no tengo un reactor nuclear, ¿pero de repente? Hubo un caso en el que rompieron TeamViewer (una empresa, no específicamente software de cliente), y a través de ellos obtuvieron acceso a muchas cuentas. Y en general, escribí al principio que amo todo lo mío.
Entonces, el siguiente paso, cambié de Zerotier a OpenVPN. Todo esta en mis manos.

El único "extranjero" es el VPS del proveedor. Bueno, estoy lanzando especialmente todo en contenedores acoplables para poder moverme instantáneamente.
Si supiera cuánto tendría que lidiar con OpenVPN, tal vez no lo haría. Para ser justos, los principales problemas se debieron precisamente a los contenedores.

Conclusión


En el próximo artículo hablaré sobre OpenVPN y las características de configuración en mis condiciones (contenedores, enrutamiento de otros dispositivos desde la red doméstica). Habrá más configuraciones, detalles técnicos y dificultades. Pero inmediatamente la segunda parte no comenzó a escribir sin esto. No estaría claro por qué tales perversiones son necesarias en absoluto.

Y por si acaso, una pregunta para quienes saben: aunque tengo un VPS y uno pequeño (512 MB de RAM), se usa menos del 1%. estadísticas del acoplador:

imagen

Y tuve la idea de lanzarlo todo como un contenedor en Google Cloud Run, Amazon Fargate o algo similar. Implementar un servidor con todo tipo de fail2ban a través de ansible no es un problema. Instale Docker también. Pero ¿por qué, si solo necesita una pequeña fracción de sus recursos?

Sin embargo, según mis cálculos, el mismo Fargate me costaría muchas veces más.

¿Quizás no entendí algo? Por lo tanto, sería interesante tener un pequeño contenedor solo para reenviar el puerto a casa, y no un VPS completo. ¿No hay tal cosa?

All Articles