Acesso seguro a uma casa inteligente na ausência de um IP público (parte 1)

Introdução


É difícil escolher um título amplo que reflita o significado, por isso descreverei imediatamente a tarefa que propus para mim.

Existe uma "casa inteligente". No meu caso, este é um servidor doméstico sem ventilador com ioBroker, embora isso não seja importante. Além do material doméstico, eu quero conectar sensores a ele do lado de fora (por exemplo, em um ESP32 de uma estufa remota). Eu decidi fazer isso através do mqtt. Acesso à interface da Internet.

A coisa de sempre. Mas existem nuances:

  • O provedor não tem como me fornecer um endereço IP público. E não há outros fornecedores.
  • Não gosto de vincular serviços específicos na nuvem. Um serviço externo também pode fechar (como a gbridge enviou uma notificação recentemente). E apenas em caso de falha, não está claro o que fazer. Prefiro o meu, que pode ser transferido, refeito com pouco sangue, se algo acontecer.
  • A segurança é importante. Não paranóia, mas colocar o ioBroker na Internet, especialmente considerando que existem vários serviços exibidos (flot ...). Não mesmo.

Além disso, quero mostrar não imediatamente o resultado, mas o processo. Como foi, como a Wishlist foi transformada, as decisões mudadas. É possível que alguns pontos possam ser resolvidos de maneira mais correta / eficiente (não sou administrador do sistema, não sou desenvolvedor). Ou talvez alguém não vá tão longe e aproveite uma solução provisória que, por exemplo, não achei segura ou conveniente para mim. Na verdade, o que é descrito nesta parte é uma opção bastante funcional, mas para mim é "intermediário".

Endereço público para mqtt


Em casa, o IP público no roteador não brilha (não estou falando de fixo, isso pode ser resolvido através de dyndns e análogos), ou seja, o provedor fornece 10.x.x.x, sem opções. Portanto, você precisa alugar um pequeno VPS e fazer um probros através dele.

A maneira mais fácil é fazer um túnel através do ssh. No servidor doméstico (chamarei iob.xxx.xx), executo:

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

Conectando à porta 1883 do servidor externo pub.xxx.xx, na realidade, você se encontra no iob: 1883 de sua casa com o contêiner mqtt (mosquito) em execução.

Naturalmente, é necessário que isso inicie automaticamente, a conexão seja restaurada após uma falha. Portanto, usei o autossh, projetando-o como um serviço.

/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

Todos os tipos de systemctl ativam / reiniciam, etc. Eu não vou descrever

Infelizmente, apesar do autossh, fui assombrado por constantes congelamentos. Então, decidi que não havia necessidade de produzir entidades e resolvi o ssh:

/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, a propósito, descobriu-se que esse provedor é tão oblíquo. Bem, ou a taxa mais barata por 45 rublos / mês, de modo torto funciona para ele. A sessão trava periodicamente, mesmo quando é simplesmente conectada via ssh (MobaXterm). Então, no final, eu pedi um VPS para outro (55 rublos / mês), e os problemas com congelamentos desapareceram.

A propósito, eu escolhi por onde levar o VPS não apenas com base no preço, mas também considerando o ping (10-20ms).

Em geral, essa opção é bastante normal, especialmente considerando que posteriormente fiz uma conexão com a Internet exclusivamente à porta 8883 via TLS. Essa. A senha do mosquito foi transmitida criptografada.

Posteriormente, tornou os certificados de cliente obrigatórios. Essa. primeiro, no nível TLS, você precisa apresentar um certificado de cliente e, em seguida, efetuar login com o nome de senha especificado no mosquito. Essa. não é tão fácil chegar à fase de pesquisa de senhas.
Portanto, no início, usei o certificado do servidor da LetsEncrypt e, devido à necessidade de certificados de cliente, mudei para autoassinatura.

Como no processo, também trabalhei no software para ESP32, notei (ou simplesmente não me lembro) que, com problemas com uma conexão VPN, a bateria será consumida muito mais rapidamente. Durante a operação normal, o ciclo: Acorde, aplique energia aos sensores, conecte-se ao WiFi, estabeleça uma conexão com o servidor mqtt, leia as leituras do sensor quando estiverem prontas, transfira para o mqtt, desligue a energia dos sensores e entre em sono profundo por 10 minutos.

Normalmente, esse ciclo leva cerca de 4 segundos. 1,5-2 segundos - conexão ao WiFi, um segundo extra devido à transição para o mqtt pelo TLS. Combina com você por 4 segundos, mesmo assim, os sensores precisam de tempo para acordar. Mas se a VPN cair (era claramente visível quando o autossh caiu), o que devo fazer? Obviamente, eu configurei para que após 20 segundos o sistema adormecesse de qualquer maneira. Mas 20 segundos em vez de 4 é muito perceptível.

Em geral, decidi que é melhor manter o servidor mqtt em um VPS externo. Agora que tudo funciona como um relógio, não tenho certeza se isso é necessário. Mas não vejo sentido em refazê-lo de volta.

Endereço público para Vis


Vis é um sistema de visualização popular no ioBroker. Você não pode se incomodar, e configurá-lo você mesmo em https e também encaminhar a porta. Além disso, ela pode solicitar uma senha no nível do aplicativo.

Mas isso não é legal. Especialmente considerando que, para o trabalho, conecta serviços adicionais. Digamos, eu desenho gráficos no flot, relativamente falando, eu me conecto a vis.xxx.xx : 8082 / vis / index.html, mas por dentro há links para gráficos vis.xxx.xxx : 8082 / flot / index.html. Em algum momento, descobriu-se que, ao conectar-se ao / vis, uma senha é solicitada e a interface gráfica é acessível sem uma senha.

Em alguns momentos, era geralmente estranho - eu estava autorizado a visualizar, vejo o gráfico, mas na parte inferior direita há uma janela translúcida de "Sem conexão com o servidor". Reescreva este bloco css para ocultá-lo. Mas, assim que comecei a usar o quadro para alternar entre gráficos na mesma tela, percebi que minha sobreposição na exibição no quadro não funcionava. (Como se viu depois, deve ser assim). Eu desligo a autorização - está tudo bem, sem palavrões.

Então, decidi no mesmo servidor externo aumentar o nginx no modo proxy reverso. E já faça autorização nele.

No navegador, funcionou. Mas o aplicativo nativo iobroker.vis do Play Market não pôde efetuar logon dessa maneira. E eu queria usá-lo. Embora este seja realmente um navegador na janela, ele possui vários recursos interessantes. Digamos que defina a escala (93% no modo vertical) e a imagem se encaixa. Em outro dispositivo com uma resolução de tela diferente, basta selecionar o coeficiente, e é isso. E no navegador você precisa se ajustar sempre ...

Ok, eu acho. Adicionarei um código complicado no URL em vez da senha. Digite vis.xxx.xx : 8082 / <sequência longa> /vis/index.html. Muitas vezes, esse truque é usado.

Quase ganhou. Mas, com falhas, a escavação mostrou que esse aplicativo Web não foi escrito corretamente. Muitos links dentro dele não são relativos, mas da raiz.

Ok, encontrei vários links, escrevi para eles, dizem eles, se o referenciador contiver esse código, ainda confie, reescreva a URL, etc. Mas eles gradualmente vieram à luz. Então, decidi que isso é torto, errado e é necessária uma abordagem diferente.

VPN


Decidi sacrificar um pouco de universalidade de acesso. Deixe-me ter acesso a partir do meu laptop, smartphone. Mas a partir dos dispositivos de outras pessoas, do cibercafé não é necessário, eu gerirei. Em seguida, você pode colocar um pequeno cliente que instalará a VPN. E dentro dele, nem SSL nem autorização são necessários. E, ao mesmo tempo, você não precisa refazer os links.

A maneira mais simples para mim era Zerotier. Para o meu sistema operacional (Windows, Android, Linux), existem clientes. E existem até arquivos prontos na janela de encaixe. Sim. Eu corro tudo no docker, sobre os recursos disso mais tarde.

Instale o cliente, insira um código exclusivo para sua rede e confirme -o na interface da Web em my.zerotier.com , se necessário, defina um endereço estático da sua rede privada pessoal (a 10.20.30.0) e é isso. Todos os clientes conectados se veem.

A única coisa com a qual tive que lidar um pouco foi "como conectar-se a um servidor remoto a partir de um dispositivo em seu WiFi doméstico sem iniciar o cliente". Bem, meu servidor doméstico já é um cliente, mesmo que ele se direcione. Acabou que tudo é simples. A rede doméstica 192.168.x.0 deve ser registrada em my.zerotier.com na seção Rotas gerenciadas, especificando como meu gateway, é claro, este é o meu servidor doméstico. Bem, na rede WiFi, configure a rota de acordo (no roteador WiFi, estática 10.20.30.0 no servidor doméstico).

Ao conectar um cliente Zerotier, você pode especificar um servidor DNS diferente. Essa. Conectei o cliente e o nome do domínio resolve não um endereço público, mas um endereço privado, porque o DNS agora aponta para o servidor doméstico, onde o dnsmasq faz o palm off para registros IP individuais da rede privada Zerotier.

Até Zerotier ficou satisfeito com a escolha efetiva de uma rota para conexão. Se eu ativar um cliente Zerotier no WiFi doméstico, o ping no computador doméstico (seu endereço IP emitido pelo Zerotier) será o mesmo par de milissegundos que sem um cliente (apenas via WiFi). Essa. Conectar-se à nuvem é apenas no primeiro momento. Trocas de tráfego adicionais são realizadas diretamente, não através da nuvem. Se você instalar, por exemplo, o OpenVPN no VPS, o mesmo tráfego será executado do cliente para o VPS e, em seguida, voltará para a mesma rede Wi-Fi no servidor doméstico.

Em princípio, existe até um chip para colocar seus servidores moon. Quase em uma rede isolada da Internet, toda essa economia deve ser implantada.

Qual é o resultado?


O ESP32 envia seus dados para o servidor mqtt implantado no VPS. Sobre TLS, certificado de cliente necessário.

Uma VPN através do Zerotier é instalada com o servidor doméstico. O Sonoff rfBridge se comunica com o firmware Tasmota através deste servidor doméstico, do mqtt ao VPS. Não há como definir o TLS com um certificado de cliente; portanto, o MQTT usual está configurado para 1883. De qualquer forma, o servidor doméstico criptografa esse tráfego usando o Zerotier.

Bem, eu me conecto ao vis diretamente da rede doméstica e da Internet ativando o cliente Zerotier. Você não pode desligá-lo, isso também funciona. Mas somente às vezes eu preciso de outros clientes VPN (por exemplo, vá para "Proibido por ILV"). Duas VPNs em um smartphone não se tornaram imediatamente amigos, mas eu não entendi.

Tudo é muito simples. Mas o verme engoliu a alma. Embora eu não tenha um reator nuclear, mas de repente? Houve um caso em que eles quebraram o TeamViewer (uma empresa, não especificamente o software cliente) e, através deles, obtiveram acesso a muitas contas. E, em geral, escrevi desde o início que amo tudo o que é meu.
Então, no próximo passo, mudei do Zerotier para o OpenVPN. Está tudo em minhas mãos.

O único "alienígena" é o VPS do fornecedor. Bem, estou lançando tudo especialmente em contêineres de encaixe para poder me mover instantaneamente.
Se eu soubesse o quanto teria que lidar com o OpenVPN, talvez não. Para ser justo, os principais problemas eram precisamente por causa dos contêineres.

Conclusão


No próximo artigo, falarei sobre o OpenVPN e os recursos de configuração em minhas condições (contêineres, roteamento de outros dispositivos da rede doméstica). Haverá mais configurações, detalhes técnicos e dificuldades. Mas imediatamente a segunda parte não começou a escrever sem isso. Não está claro por que essas perversões são necessárias.

E, por precaução, uma pergunta para quem sabe: embora eu tenha um VPS e um pequeno (512 MB de RAM), ele é usado menos de 1%. docker stats:

imagem

E tive a ideia de lançar tudo como um contêiner em algum Google Cloud Run, Amazon Fargate ou algo semelhante. A implantação de um servidor com todos os tipos de fail2ban através do ansible não é um problema. Instale o Docker também. Mas por que, se você precisar de apenas uma pequena fração de seus recursos?

No entanto, de acordo com meus cálculos, o mesmo Fargate me custaria muitas vezes mais.

Talvez eu não tenha entendido alguma coisa? Portanto, seria interessante ter um pequeno contêiner puramente para encaminhar o porto para casa e não um VPS inteiro. Nao existe tal coisa?

All Articles