Substituí o servidor de controle Tailscale pelo Headscale e meus dispositivos não perceberam

Tailscale é um daqueles serviços que adicionei quase por acidente e rapidamente se tornou parte do meu fluxo de trabalho. Após a implementação inicial, ele funcionou silenciosamente em segundo plano e nunca exigiu atenção. Eu sabia que o WireGuard fazia a maior parte do trabalho interno. Até tentei substituir o Tailscale pelo WireGuard bruto, mas o CGNAT o eliminou no meu servidor doméstico.

Mas desta vez eu tinha um plano diferente. Já tinha um VPS com IP estático, alugado para outros projetos. Então, eu poderia seguir o mesmo caminho e reimplantar o WireGuard e portar minha memória muscular do cliente Tailscale ou procurar outra coisa. Foi quando me deparei com o Headscale. Acontece que ainda posso usar o mesmo cliente Tailscale, mas o servidor de controle está no meu VPS em vez da nuvem do Tailscale. O servidor em si era surpreendentemente simples, mas adicioná-lo à minha configuração existente era outra história.

Troquei o Tailscale pelo Pangolin para acesso remoto e foi muito mais fácil do que eu esperava

Eu não esperava que essa mudança fosse tão fácil.

O servidor de controle em que eu nunca soube que confiava

Tailscale tem cérebro e eles não são meus

Tenho usado o Tailscale em um servidor Debian doméstico desde o primeiro dia (quase). Não só era confiável, mas eu realmente precisava dele para acessar meus serviços internos quando estava fora de casa. Ambos os meus ISPs estavam por trás do CGNAT, o que tornou o Tailscale uma escolha óbvia.

Foi um dos poucos serviços da minha pilha que nunca exigiu atenção. Criei uma conta, instalei o cliente em todos os meus dispositivos e loguei. Sempre que precisava acessar um dos meus serviços internos em casa, simplesmente me conectava à minha rede back-end.

Simplesmente funcionou, o que me fez pensar no que estava acontecendo nos bastidores. E essa curiosidade me levou ao Tailscale Brain Self-Service. Não por causa da paranóia da privacidade, e não porque eu quisesse substituí-la; era apenas curiosidade sobre o que realmente estava sob a simples escama da cauda.

Headscale era uma implementação auto-hospedada do servidor de controle Tailscale. Ele substituiu o plano de controle Tailscale, não o próprio WireGuard. No fundo ainda era o mesmo WireGuard cuidando de tudo. E o bom é que não precisei tocar no cliente do meu aparelho; era o mesmo aplicativo Tailscale em todos os lugares. A única coisa que mudou foi que a autenticação, a identidade e a coordenação de pares foram movidas para o meu servidor.

No papel, tudo parecia bonito e simples. Já tinha um VPS com recursos suficientes. Quero dizer, quanto trabalho isso daria? Com um arquivo Docker Compose e algumas etapas de configuração, estarei pronto e funcionando em minutos. O servidor não foi a parte que mais me custou. Tudo ao seu redor aconteceu.

Um contêiner Docker e tudo quebrou

Meu corretor reverso tinha outros planos

A configuração inicial foi bastante simples. Peguei o Docker Compose e o implantei usando pilhas Portainer. Passou em menos de alguns segundos. Eu acho que é isso; a parte difícil já havia passado. Eu poderia simplesmente criar um usuário e gerar chaves para conectar meus dispositivos. Mas nunca cheguei a essa parte. A API estava simplesmente inacessível. A princípio parecia um problema do Headscale, mas acabou sendo algo totalmente diferente.

services:
 headscale:
   image: headscale/headscale:latest
   container_name: headscale
   restart: unless-stopped
   command: serve
   volumes:
     - ./config:/etc/headscale
     - ./data:/var/lib/headscale
   networks:
     - pangolin

networks:
 pangolin:
   external: true

Meu VPS já estava rodando o Pangolin e o Pangolin estava usando o Traefik para lidar com o proxy reverso. Então presumi que adicionar rótulos do Docker seria suficiente para mostrar o Headscale usando o Traefik, mas nada aconteceu. O contêiner Traefik não estava visível. Examinei vários documentos e alguns comandos aqui e ali. Finalmente, quando eu corri docker inspect traefik a equipe descobriu que a instância do Pangolin Traefik estava apenas olhando para a própria API do Pangolin e nenhum provedor Docker estava habilitado.

Foi quando percebi que Headscale estava bem; a questão nem estava relacionada a isso. Foi um artefato de como o Pangolin configurou o Traefik e só deveria funcionar dessa forma. Mas quando localizei o verdadeiro culpado, o arquivo de configuração do Traefik, ele era somente leitura anexado ao contêiner. Isso significava que não era possível editar o arquivo de dentro do contêiner porque as alterações precisavam ser feitas diretamente no host.

Finalmente, finalmente escrevi o bloco roteador/serviço dynamic_config.yml arquivo em vez de depender da descoberta automática usando rótulos do Docker. Agora o Traefik estava funcionando, confirmei com a resposta curl, mas agora o Headscale começou a funcionar. Quando criei o usuário, executei outro comando para gerar as preauthkeys, mas o Headscale esperava um ID numérico para o sinalizador –user, não o nome de usuário recém-criado.

headscale-router:
 rule: "Host(`headscale.example.com`)"
 service: headscale-service
 entryPoints:
   - websecure
 tls:
   certResolver: letsencrypt

headscale-service:
 loadBalancer:
   servers:
     - url: "http://headscale:8080"

Feito isso, me deparei com outro grande problema: server_url e base_domain não podiam compartilhar o mesmo domínio. Headscale requer que base_domain seja um subdomínio da URL do servidor, não o mesmo domínio. Depois que isso foi resolvido, finalmente consegui conectar meus dispositivos à rede Headscale. Ironicamente, a parte que me preocupava, conectar os dispositivos, acabou sendo a parte mais fácil de todo o projeto.

Os dois dispositivos conectados e nada parecia diferente

Esse é o ponto principal

Depois da parte difícil, chegou a hora do verdadeiro teste. Gerei chaves de pré-autenticação reutilizáveis ​​para não precisar de novas para cada dispositivo. Inicialmente decidi não incluir meu servidor doméstico de produção neste teste porque muitos serviços ativos dependiam dele. E então conectei os dois dispositivos principais, o PC para jogos e o MacBook Pro, à rede usando apenas dois comandos. Um comando para sair da minha conta Tailscale e outro para fazer login no meu servidor Headscale auto-hospedado.

tailscale logout
tailscale up --login-server (server_url) --authkey (key)

E esta foi uma das partes convenientes; ele usou o mesmo cliente Tailscale instalado em meus dispositivos. Quando a configuração real do Headscale foi feita no lado do servidor, era um cliente Tailscale e um único comando de login. Depois que os dois dispositivos foram conectados, executei o comando headscale node list e imediatamente vi os dois dispositivos online com endereços IPv4 e IPv6 atribuídos.

Vi evidências reais de que funciona quando testei um dispositivo em outro. Primeiro, tentei conectar meu MacBook a um PC para jogos; falhou na primeira vez, provavelmente devido a um problema de firewall do Windows no computador. Então verifiquei o MacBook no meu computador; funcionou instantaneamente e os resultados me contaram uma história interessante. As primeiras respostas estavam na faixa de 90 a 100 ms, mas depois diminuíram para a faixa de 5 a 20 ms. Bem, foi o retransmissor DERP público da Tailscale que fez o trabalho pesado.

Tudo aconteceu na CLI e a única informação de status que recebi foi de headscale nodes list equipe. Foi aí que comecei a procurar uma boa interface web. Embora não seja fornecido oficialmente pela Headscale, sua documentação sugeria o uso de algumas interfaces de usuário de terceiros. Havia mais de dez opções de código aberto, mas escolhi duas, Placa de cabeça e headscale-uipor suas interfaces modernas com aparência de Tailscale.

Headplane ofereceu recursos avançados, como listas de controle de acesso (ACLs), suporte OpenID Connect (OIDC) e a capacidade de editar configurações de DNS, mas escolhi headscale-ui por sua simplicidade e menor consumo de recursos em meu VPS. Encontrei alguns erros como “Política ACL não encontrada”, que corrigi com um comando CLI rápido (conjunto de políticas) e tudo correu bem depois disso.

Minha primeira impressão do painel? Apesar das mudanças na infraestrutura, parecia surpreendentemente semelhante ao console de administração do Tailscale. Na própria página inicial, meus dois dispositivos estavam verdes, online e visíveis instantaneamente. Headscale não fez Tailscale parecer diferente, o que é o sinal mais positivo de que o experimento funcionou.

Cloudflare Mesh me deu tudo o que a Tailscale fez, menos a outra empresa na minha rede

Menos empresas, igualdade de acesso, sem reclamações.

Mesma rede, mãos diferentes

Não iniciei este experimento com o objetivo de substituir o Tailscale na minha rede. Headscale não torna minha rede mais rápida e não mudou o funcionamento do Tailscale. O valor veio de mover o plano de controle para minha infraestrutura, mantendo a mesma experiência Tailscale. Houve alguns obstáculos ao longo do caminho, mas assim que foram superados, Headscale começou a parecer algo com o qual eu realmente poderia me comprometer. Embora eu tenha emprestado o bastão DERP do Tailscale, pretendo hospedá-lo sozinho se eventualmente decidir dar ao Headscale um lugar permanente em minha pilha.

Link da fonte