Economize com IP fixo! Se você possui um servidor caseiro ou laboratório em uma máquina/VM Linux e quer acessar seus serviços usando seu próprio domínio (ex: jaldo.com.br), este tutorial ensina como criar seu próprio DDNS (Dynamic DNS) totalmente automatizado com a API da Cloudflare.
Nota: Em breve publicarei um post detalhado sobre como comprar e configurar um domínio do zero na Cloudflare. Para este tutorial, consideramos que seu domínio já está apontado para os servidores DNS da Cloudflare.
Requisitos Prévia do Projeto
- Conexão com IP Público Dinâmico: O IP fornecido pelo seu provedor de internet (ISP) deve ser público.
⚠️ Este método NÃO funciona se você estiver sob CGNAT (onde o IP externo do roteador é compartilhado com vários clientes). Nesses casos, soluções como No-IP, Cloudflare Tunnels ou Tailscale são mais indicadas.
- Uma Máquina Virtual ou Servidor Linux: Qualquer distribuição (Ubuntu, Debian, RHEL, Arch, Alpine, etc.).
- Domínio próprio na Cloudflare: Com permissão para gerar API Tokens.
Passo 1: Instalar dependências no Linux
O script utiliza as ferramentas curl (para requisições HTTP) e jq (para manipular respostas em formato JSON da API). Instale conforme sua distribuição:
Debian / Ubuntu / Linux Mint:
sudo apt update && sudo apt install -y curl jq
RHEL / Oracle Linux / Rocky / AlmaLinux:
sudo dnf install -y curl jq
Arch Linux:
sudo pacman -S --noconfirm curl jq
Alpine Linux:
sudo apk add curl jq
Passo 2: Gerar API Token na Cloudflare
- Acesse o painel da Cloudflare em dash.cloudflare.com.
- Vá no seu Perfil de Usuário → Tokens de API.
- Clique em Criar Token e escolha o modelo Editar DNS da Zona.
- Defina a permissão da zona como:
Zona - Registros de DNS - Editar.
- Copie o Token gerado (ele será usado no script).
Passo 3: Criar o Shell Script de DDNS
Abra o terminal no Linux e crie o arquivo no diretório executável do sistema:
sudo nano /usr/local/bin/cloudflare-ddns.sh
Cole o código do script abaixo. Lembre-se de alterar as variáveis API_TOKEN e ENTRADAS_DNS com seus dados:
#!/bin/bash
# ==============================================================================
# NOME DO SCRIPT: cloudflare-ddns.sh
# DESCRIÇÃO: Atualiza o IP do domínio na Cloudflare sempre que o IP público mudar.
# AUTOR: Jaldo Paz da Silva - jaldo.com@hotmail.com
# DATA: 19/03/2026
# VERSÃO: 1.0
# ==============================================================================
# Insira o Token de API gerado no painel da Cloudflare
API_TOKEN="token_gerado_na_cloudflare"
# Coloque aqui todas as suas entradas de DNS do tipo A que deseja atualizar
ENTRADAS_DNS=(
"jaldo.com.br"
"www.jaldo.com.br"
)
# Arquivo para cache do último IP verificado
IP_PUBLICO_ATUAL_ARQUIVO="/tmp/ip_publico_atual.txt"
DATA=$(date '+%d-%m-%Y')
DIR_LOG="/var/log/atualiza-cloudflare"
LOG_ARQUIVO="$DIR_LOG/cloudflare-ddns-$DATA.log"
[ -d "$DIR_LOG" ] || mkdir -p "$DIR_LOG"
log() {
echo "$(date '+%d-%m-%Y %H:%M:%S') - $1" | tee -a "$LOG_ARQUIVO"
}
# Consulta o IP público atual utilizando contingências
IP=$(curl -4 -s --max-time 5 https://api.ipify.org)
[[ ! $IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] && \
IP=$(curl -4 -s --max-time 5 https://ifconfig.me)
[[ ! $IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] && \
IP=$(curl -4 -s --max-time 5 https://icanhazip.com | tr -d '\n')
IP_PUBLICO_ATUAL=$IP
if [ -z "$IP_PUBLICO_ATUAL" ]; then
log "ERRO: Não foi possível obter o IP público!"
exit 1
fi
# Se o IP não mudou desde a última checagem, encerra a execução
if [ -f "$IP_PUBLICO_ATUAL_ARQUIVO" ]; then
OLD_IP=$(cat "$IP_PUBLICO_ATUAL_ARQUIVO")
if [ "$OLD_IP" == "$IP_PUBLICO_ATUAL" ]; then
log "IP não mudou ($IP_PUBLICO_ATUAL). Nada a atualizar."
exit 0
fi
fi
log "Novo IP detectado: $IP_PUBLICO_ATUAL"
# Atualizando os registros no DNS da Cloudflare
for ENTRADA in "${ENTRADAS_DNS[@]}"; do
DOMINIO=$(echo "$ENTRADA" | sed 's/^www\.//')
log "Atualizando: $ENTRADA"
# Busca o ZONA_ID na Cloudflare
ZONA_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=${DOMINIO}" \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" | jq -r '.result[0].id')
if [ "$ZONA_ID" = "null" ] || [ -z "$ZONA_ID" ]; then
log "ERRO: Não foi possível obter ZONA_ID para $DOMINIO"
continue
fi
# Busca o ENTRADA_ID do registro DNS
ENTRADA_ID=$(curl -s -X GET \
"https://api.cloudflare.com/client/v4/zones/${ZONA_ID}/dns_records?name=${ENTRADA}" \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" | jq -r '.result[0].id')
if [ "$ENTRADA_ID" = "null" ] || [ -z "$ENTRADA_ID" ]; then
log "ERRO: Não foi possível obter ENTRADA_ID para $ENTRADA"
continue
fi
# Atualiza a entrada de DNS com o novo IP
RESPOSTA=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONA_ID}/dns_records/${ENTRADA_ID}" \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"${ENTRADA}\",\"content\":\"${IP_PUBLICO_ATUAL}\",\"ttl\":120,\"proxied\":false}")
SUCESSO=$(echo "$RESPOSTA" | jq -r '.success')
ERROS=$(echo "$RESPOSTA" | jq -c '.errors')
if [ "$SUCESSO" != "true" ]; then
log "ERRO ao atualizar $ENTRADA → $ERROS"
else
log "OK → $ENTRADA atualizado para $IP_PUBLICO_ATUAL"
fi
done
# Salva o IP atualizado no cache local
echo "$IP_PUBLICO_ATUAL" > "$IP_PUBLICO_ATUAL_ARQUIVO"
Passo 4: Conceder permissão de execução
Dê permissão para que o Linux consiga rodar o script:
sudo chmod +x /usr/local/bin/cloudflare-ddns.sh
Faça um teste manual executando o script pela primeira vez:
sudo /usr/local/bin/cloudflare-ddns.sh
Passo 5: Agendar na Cron (Automação)
Para garantir que a verificação rode automaticamente a cada 5 minutos sem intervenção humana, adicione a tarefa no agendador de tarefas do sistema (Cron):
sudo crontab -e
Cole a linha abaixo no final do arquivo:
*/5 * * * * /usr/local/bin/cloudflare-ddns.sh > /dev/null 2>&1
Conclusão e Logs
Pronto! Seu DDNS caseiro está configurado. Caso seu provedor altere seu IP público, em até 5 minutos seus domínios apontarão automaticamente para o novo endereço.
Você pode acompanhar as atualizações lendo os logs gerados em /var/log/atualiza-cloudflare/ com o comando:
tail -f /var/log/atualiza-cloudflare/cloudflare-ddns-*.log