VPN: Headscale com Fly.io Sem Exposição de Portas

Se você quer criar uma VPN para o seu homelab sem precisar de port forwarding ou IPv4 público (usuários CGNAT), este guia é para você. Neste tutorial, você vai aprender a usar o headscale, um servidor open source que funciona com o Tailscale, para criar uma rede privada e segura entre os seus dispositivos. Você vai usar o Docker para instalar o headscale em uma conta gratuita da fly.io, uma plataforma de hospedagem em nuvem para testes de aplicativos. Em seguida, você vai conectar os seus dispositivos ao headscale usando o Tailscale, um cliente VPN simples e eficiente. Além disso, você vai ter um domínio personalizado fly.dev e certificados SSL.

Introdução

Headscale é uma implementação de código aberto do servidor de controle do Tailscale, que é uma tecnologia que permite criar uma rede privada virtual entre dispositivos usando uma rede pública como a Internet. Com headscale, você pode hospedar o seu próprio servidor de controle e gerenciar as suas redes privadas, sem depender de serviços de terceiros. Headscale usa o protocolo WireGuard para criptografar e rotear o tráfego entre os dispositivos, e oferece recursos como DNS, ACL, Taildrop, e muito mais.

Fly.io é uma plataforma de hospedagem em nuvem que fornece aos desenvolvedores um ambiente simplificado e altamente otimizado para hospedar seus aplicativos e sites. Com o fly.io, você pode implantar seus aplicativos em diferentes regiões do mundo, usando recursos como balanceamento de carga, certificados SSL, domínios personalizados, e muito mais. Você também pode usar o flyctl, uma ferramenta de linha de comando, para configurar, criar, implantar e gerenciar seus aplicativos no fly.io. Fly.io oferece uma avaliação gratuita para novos usuários.

Pré-Requisitos

Um computador com Docker instalado.

Uma conta da fly.io, que pode ser a gratuita. (É preciso ter um cartão de crédito para validação.)

Headscale: Instalação e configuração

Em primeiro lugar vamos criar uma pasta que vai ser usada para o processo de instalação e configuração do headscale no guia vamos usar a pasta /mnt/docker/headscale

Abaixo segue o caminho para os arquivos

/mnt
  /docker
    /headscale
      - docker-compose.yaml
      - fly.toml
      - Dockerfile
      /config
        - config.yaml

Criando o Dockerfile

Um Dockerfile é um arquivo que contém as instruções para construir uma imagem docker.

Use o comandos abaixo para cria-lo

sudo mkdir -p /mnt/docker/headscale/config
sudo nano /mnt/docker/headscale/Dockerfile

Dockerfile

FROM alpine:3.19.1
WORKDIR /tmp
# ---
RUN apk update \
        && apk upgrade -a

# ---
# Use the latest stable version of headscale
ARG HEADSCALE_VERSION=0.22.3
ARG HEADSCALE_SHA256=41eb475ba94d2f4efdd5b90ca76d3926a0fc0b561baabf6190ca32335c9102d2
    # Download Headscale
    RUN wget -q -O headscale https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_amd64; \
        echo "${HEADSCALE_SHA256}*headscale" | sha256sum -c -; \
        chmod +x headscale; \
        mv headscale /usr/local/bin/;
COPY ./config/config.yaml /etc/headscale/config.yaml
ENTRYPOINT ["/usr/local/bin/headscale", "serve"]

Copie o cole o conteúdo no arquivo salve e saia.

Este Dockerfile usa a imagem oficial do Alpine Linux como base, na versão 3.19.1. Ele atualiza o sistema, aplica correções de segurança, e baixa o binário do headscale do GitHub.

Criando o Arquivo config.yaml

Esse arquivo que define os parâmetros de funcionamento do headscale, como o endereço do servidor, o nome da rede, o método de autenticação, etc. Você pode usar o seguinte exemplo de configuração do headscale:

sudo nano /mnt/docker/headscale/config/config.yaml

config.yaml

---
server_url: https://nome_da_aplicação.fly.dev # Substitua pelo seu domínio
listen_addr: 0.0.0.0:8099
metrics_listen_addr: 0.0.0.0:9090
private_key_path: /data/private.key
noise:
  private_key_path: /data/noise_private.key

ip_prefixes:
  - 100.64.0.0/10
  - fd7a:115c:a1e0::/48

derp:
  server:
    enabled: false
  urls:
    - https://controlplane.tailscale.com/derpmap/default
  auto_update_enabled: true
  update_frequency: 24h

# Disables the automatic check for headscale updates on startup
disable_check_updates: true

db_type: sqlite3
db_path: /data/db.sqlite3

# TLS
tls_cert_path: ""
tls_key_path: ""

log:
  format: text
  level: info

dns_config:
  override_local_dns: true
  nameservers:
    - 1.1.1.1
    - 1.0.0.1
    - 2606:4700:4700::1111
    - 2606:4700:4700::1001

  magic_dns: true
  base_domain: seudominio.com

unix_socket: /var/run/headscale.sock
unix_socket_permission: "0770"

logtail:
  enabled: false
randomize_client_port: false

  • server_url: é o endereço do servidor do headscale, que deve ser o mesmo que o domínio do seu aplicativo na fly.io. Você pode obter o domínio do seu aplicativo na página de configurações do fly.io, ou usando o comando “flyctl domains list”

  • listen_addr: é a porta que o headscale vai escutar, que deve ser a mesma que a porta que você vai expor no seu arquivo docker-compose, que você vai criar na próxima seção.

  • private_key_path: é o caminho para a chave privada do headscale, que é gerada automaticamente pelo headscale na primeira vez que ele é executado. Você deve montar um volume para persistir essa chave, como você vai ver na próxima seção.

  • noise: é a seção que define as configurações do Noise, que é um protocolo de criptografia que o headscale usa para se comunicar com os dispositivos.
    • private_key_path: é o caminho para a chave privada do Noise, que é gerada automaticamente pelo headscale na primeira vez que ele é executado. Você deve montar um volume para persistir essa chave, como você vai ver na próxima seção.

  • magic_dns: é a opção que define se o headscale vai habilitar o Magic DNS ou não. O Magic DNS é um recurso que permite usar nomes de domínio simples para acessar os dispositivos na rede, como laptop.seudominio.com ou desktop.seudominio.com. Neste exemplo, estamos habilitando o Magic DNS, pois queremos usar nomes de domínio simples para acessar os dispositivos.

  • base_domain: é o domínio base que o headscale vai usar para o Magic DNS. Você deve substituir esse valor pelo seu próprio domínio

Criar um arquivo docker-compose

Um docker-compose é um arquivo que define os serviços, as redes e os volumes que compõem a sua aplicação docker. Você pode usar o exemplo abaixo de docker-compose para o headscale:

sudo nano /mnt/docker/headscale/docker-compose.yaml

docker-compose.yaml

---
version: "3.9"
services:
  headscale:
    container_name: headscale
    volumes:
      - ./config/config.yaml:/etc/headscale/config.yaml
      - headscale:/data
    ports:
      - 8099:8099
    build: .
    restart: unless-stopped
volumes:
  headscale:
    driver: local

Salve e saia do arquivo.

Este docker-compose faz o seguinte:

  • Define a versão do docker-compose, que deve ser compatível com a versão do docker que você está usando.
  • Define o serviço headscale, que é o único serviço da sua aplicação.
  • Define que o serviço headscale deve ser construído a partir do Dockerfile que você criou na seção anterior

Criando o Arquivo fly.toml

O arquivo fly.toml é um arquivo de configuração que você pode usar para personalizar o seu aplicativo na plataforma fly.io.

sudo nano /mnt/docker/headscale/fly.toml

fly.toml

app = "nome_da_aplicação"
kill_signal = "SIGINT"
kill_timeout = 5

[metrics]
port = 9090
path = "/metrics"

[experimental]
  auto_rollback = true

[[services]]
  internal_port = 8099
  protocol = "tcp"
  [services.concurrency]
    hard_limit = 25
    soft_limit = 20
    type = "connections"

  [[services.ports]]
    force_https = true
    handlers = ["http"]
    port = 80

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443

  [[services.tcp_checks]]
    grace_period = "1s"
    interval = "15s"
    restart_limit = 0
    timeout = "2s"

[mounts]
source = "head_data"
destination = "/data"

Instalando o Flyctl

Agora que você já criou todos os arquivos necessários, o próximo passo é instalar o flyctl. Para isso, execute os seguintes comandos:

curl -L https://fly.io/install.sh | sh

Criando a Aplicação

Primeiramente crie um registro no fly.io

fly auth signup

Escolha uma das opções de cadastro: com email, senha e nome; ou com a sua conta do Google.

Confirme o seu email e ative a sua conta

Para fazer login pelo flyctl, você pode seguir estes passos:

Execute o comando abaixo para abrir a página de login no seu navegador:

 fly auth login 

Digite o seu email e senha, ou clique em “Sign in with Google” se você usou essa opção para se cadastrar

Aguarde a confirmação de que você está conectado ao fly.io

Escolha um nome para a aplicação o comando ficaria assim

fly apps create nome_da_aplicação

Proximo passo é adicionar um volume como no comando abaixo

fly volumes create --app nome_da_aplicacao --region gru --size 1 head_data

Navegue até o diretório /mnt/docker/headscale, que é onde vamos trabalhar neste guia. Em seguida, execute os comandos abaixo para criar a imagem docker do headscale.

sudo docker compose build

Aguarde finalizar o processo de criação da imagem.

Finalmente para fazer o deploy da sua aplicação, basta executar o seguinte comando:

fly deploy

Para verificar se o seu deploy foi bem-sucedido, acesse a sua dashboard no fly.io e clique em monitoring. Se não houver nenhum erro, você pode testar a sua aplicação acessando o link que aparece na tela.

https://nome_da_aplicacao.fly.dev/windows

Parabéns sua VPN já esta funcionando.

Acessando o Headscale

Precisamos acessar agora o headscale para criar os usuarios e permitir o acesso dos clientes para isso use o comando abaixo dentro do diretorio que voce criou a aplicação

fly ssh console

Para criar um usuário para algum cliente execute o comando:

headscale user create usuario

Conclusão

Concluímos a instalação do servidor Headscale. Para se conectar a ele, siga o guia passo a passo sobre como configurar o cliente Tailscale para se conectar à nossa VPN.

Fontes Utilizadas:

Dockerfile Docs. Nessa página, você pode encontrar todas as instruções que você pode usar em um Dockerfile, o formato do arquivo, os exemplos de uso e as melhores práticas.

GitHub – juanfont/headscale: An open source, self-hosted implementation of the Tailscale control server: o repositório oficial do headscale no GitHub, onde você pode encontrar o código fonte, as instruções de instalação, a documentação e suporte.

Fly.io developer documentation · Fly Docs: a documentação oficial do fly.io, onde você pode encontrar guias, tutoriais, referências e recursos sobre como usar a plataforma.

Deixe um comentário