Expondo serviços da sua rede local para a internet com o Cloudflare Tunnel

· 5 minutes

Desde que comecei e me aventurar pelo universo de aplicações self-hosted, expô-las fora da minha rede local sempre foi um problema, principalmente devido ao provedor de internet que tenho disponível na minha região, pois o mesmo não oferece esse tipo de serviço.

Devido a esse empasse, sempre tive em busca de soluções que me auxiliassem com esse tipo de configuração sem depender do meu provedor de internet.

Por um longo período o Dataplicity foi meu melhor companheiro nessa situação, pois as aplicações eram hospedadas na minha Raspberry Pi 3B+ e facilmente poderiam ser expostos para a internet.

Com o passar do tempo novas soluções foram surgindo e dentre elas, o Cloudflare Tunnel foi o que mais me chamou a atenção, por ser um serviço free e pela praticidade na configuração.

Neste post irei descrever algumas dicas para a configuração do Cloudflare Tunnel junto ao meu homelab.

O serviço funciona de uma forma bem simples, primeiro é necessário ter um domínio válido, o meu por exemplo é bergpb.dev, e uma conta criada no serviço Cloudflare.

Após isso adicionar o seu domínio a sua conta Cloudflare, e instalar o serviço do cloudflared (ou executar a imagem docker com esse serviço) para que ele possa realizar o vínculo entre sua máquina rodando localmente e o domínio adicionado na sua conta do Cloudflare.

Não irei me estender muito em como realizar a configuração pois existem inúmeros tutorials disponíveis de como realizar esse processo. Neste post irei focar apenas algumas facilidades de como configurar e adicionar novos serviços.

Aqui alguns tutoriais que recomendo para realizar a configuração e instalação do Cloudflare Tunnel:

Após você ter conferido os links acima, sabemos que é possível cadastrar subdomínios e vincular novos serviços a ele, e com o Cloudflare Tunnel podemos rodar uma aplicação em um container, por exemplo, sendo exposto localmente na porta 8000, e apontar essa aplicação para um determinado subdomínio no Cloudflare.

Abaixo um exemplo de como essa configuração pode ser feita utilizando o arquivo config.yml disponível na pasta $HOME/.cloudflared:

tunnel: <seu-tunnel-id>
credentials-file: <caminho-para-arquivo-com-credenciais>.json
ingress:
  - hostname: "blog.bergpb.dev"
    service: http://192.168.6.2:8000

Na definição do arquivo acima estamos realizando o apontamento da aplicação rodando localmente em um container na porta 8000 para o subdomínio blog.bergpb.dev, assim o serviço estará disponível externamente através dessa url. Isso irá ocorrer assim que o subdomínio for cadastrado com o cloudflared CLI, e o serviço do cloudflared for reiniciado.

Para isso criei um script em bash chamado manage e adicionei o mesmo no PATH para realizar essa tarefa, assim posso facilmente realizar a adição de novos subdomínios e aplicar essa configuração:

#!/bin/bash

SITE=$1

recreate_cloudflared_service () {
echo "---------Recreating cloudflared service----------"
sudo cloudflared service uninstall
sudo rm /etc/cloudflared/config.yml
sudo cloudflared --config $HOME/.cloudflared/config.yml service install
systemctl status cloudflared --no-pager
echo "-------------------Done!!!-----------------------"
}

if [[ -z "$SITE" ]]; then
    echo "Provide a site name. Example: subdomain.yoursite.com"
    echo "Site name not provided, only restarting cloudflared service"
    recreate_cloudflared_service
    exit 0
fi

echo "Adding CNAME entry $SITE"

cloudflared tunnel route dns \
$(cloudflared tunnel list -n localserver | head -3 | tail +3 | awk '{print $1}') \
$SITE

recreate_cloudflared_service

Executando o script:

manage blog.bergpb.dev

Esse script pode receber um argumento chamado SITE, caso o mesmo for fornecido pelo usuário ao executar o script, o mesmo irá adicionar esse novo site ao Cloudflare Tunnel e reconfigurar o serviço para que as alterações sejam aplicadas. Caso o argumento não for fornecido, o script irá apenas reconfigurar o serviço do cloudflared.

Outra dica bem interessante é que podemos utilizar wildcards no arquivo config.yml, com essa configuração podemos adicionar todos os subdomínios cadastrados no Cloudflared Tunnel e direcionar para um servidor proxy rodando localmente, aqui utilizo o Nginx Proxy Manager rodando em um container, o mesmo se torna uma ótima escolha principalmente pela facilidade de configuração através do navegador.

Aqui como está meu arquivo de configuração atualmente:

tunnel: <seu-tunnel-id>
credentials-file: <path-para-arquivo-com-credenciais>.json
ingress:
- hostname: "*.bergpb.dev"
    service: http://192.168.6.2:80
    originRequest:
      noTSLVerify: true

Com a configuração acima, todo subdomínio do site bergpb.dev anteriormente adicionado no Cloudflare, será direcionado ao nginx-proxy-manager, rodando em um container na porta 80, e ele realizará o proxy para a aplicação rodando em sua respectiva porta no servidor local cadastrada com o nginx-proxy-manager.

blog.bergpb.dev

Isso deixa a configuração bem simples e muito versátil. Além disso por padrão, as aplicações estarão sendo acessadas com https, mesmo que elas não tenham algum certificado ssl cadastrado localmente. Todo tráfego externo será criptografado até chegar na sua rede interna.

A configuração noTLSVerify desabilita a verificação de um certificado instalado na origem, assim não se torna necessário um certificado SSL instalado localmente.

Outra configuração muito interessante é que vários protocolos são aceitos no Cloudflare Tunnel, um deles é o ssh, tornando possível o acesso externo ao servidor através de uma conexão ssh segura. Mais informações sobre essas configurações na documentação oficial.

Espero que este post tenha ajudado de alguma forma com essa configuração.

Bons estudos e até breve.

Referências: