+ Responder ao Tópico



  1. #1

    Post Artigo - DDNS.com.br para linux funcionando com perfeição.

    Galera, acho que esse não é o espaço destinado a colocar artigos/tutoriais, mas confesso envergonhado que passei mais de 40min tentando descobrir como criar um novo tutorial/artigo no wiki e não consegui. Se alguém puder me ensinar ficarei muito agradecido.

    Vamos ao que interessa:

    A alguns dias precisei de uma solução de DNS dinâmico para utilizar em servidores linux que não tinham um ip fixo. Já utilizei anteriormente o no-ip.com, porém acontece que eles mudaram a politica deles obrigando os usuários a fazerem login no site de tempo em tempo para o domínio não ser desativado.


    Já havia experimentado o ddns.com.br, porém apenas pra windows e descobri que esse tem uma versão linux tbm.
    O problema é que essa versão linux tem problemas grotescos de erros na programação dos scripts, levando a maquina muitas vezes a loops infinitos e rodar centenas de processos iguais simultânea mente, além de não suportar o caso de a maquina estar atrás de um router com ip dinâmico.


    Quem tiver interesse de saber todos os problemas que achei nos scripts pode ler no final desse artigo uma carta que enviei para a empresa responsável pelo ddns.com.br e não obtive resposta alguma.


    Resolvi refazer os scripts e implementar a solução com router + nat unindo os vários scripts em um único arquivo ddns.sh


    Seu conteúdo é o que se segue, bastando apenas copiar e colar em em um arquivo ddns.sh e copia-lo para /usr/local/sbin/ddns.sh


    De um chmod +x /usr/local/sbin/ddns.sh para adicionar permissão de execução ao mesmo.



    #!/bin/bash
    ##################################################
    #
    # Script para testar se houve mudança de end. IP. Caso positivo, atualiza
    #
    #################################################
    # Para um correto funcionamento desse script é necessário que seja adicionado 2 entradas na crontab, isso pode ser feito copiando
    # as próximas 2 linhas que estão comentadas com # para /etc/cron.d/ddns e em seguida é necessário reiniciar a cron.

    # 0-59/2 * * * * root /usr/local/sbin/ddns.sh
    # 00 * * * * root sleep 30 ; /usr/local/sbin/ddns.sh yes

    #
    # As seguintes variáveis devem ser configuradas:
    #
    #Seu end. DDNS (ex.: meuendereco.ddns.com.br)(OBRIGATORIO)
    DOMINIO=""
    # Sua senha para o domínio(OBRIGATORIO)
    SENHA=""
    # Endereço da interface com acesso a internet ex: eth0 wlan0
    INTERFACE=""
    # Se estiver atrás de um roteador(NAT) coloque "yes" se estiver com o ip real diretamente na interface citada acima coloque "no"
    NAT="yes"

    # Para descobrir o ip de internet baixamos um html de um servidor remoto que retornará o ip real.
    # Podemos usar o serviço gratuito "www.qualemeuip.com.br" ou um serviço próprio.
    # A vantagem de usar um serviço próprio é que teremos certeza da sintaxe retornada, caso o "www.qualemeuip.com.br" mude a sintaxe da pagina
    # isso poderia fazer com que esse script não consiga pegar o ip corretamente.
    # Segue abaixo o conteúdo comentando com # do ip.php para se colocar em um servidor com ip fixo e suporte a php.

    # <?php
    # print(getenv("REMOTE_ADDR"));
    # ?>


    # Para usar o serviço do "www.qualemeuip.com.br) preencha a variável abaixo com o ip 70.84.93.247 ou com o nome "www.qualemeuip.com.br"
    # utilizar o ip diretamente é mais rápido mas se esse vier a mudar o scrip deixará de funcionar.
    QUALEMEUIP="" #"70.84.93.247"

    # Para usar o serviço próprio a variável NATIP deve ser preenchida com o ip/ip.php, onde o ip é o numero de ip do servidor onde o ip.php encontra-se.
    # Se preenchida ela é quem vai retornar o ip real do cliente para o script.
    NATIP=""

    # A variável IP deverá ser setada apenas no caso de o ip ser fixo, caso contrario devera ser deixada em branco
    IP=""
    ##################################################
    TMPDIR=/tmp #Diretório temporário
    BINDIR=/usr/local/sbin
    ##################################################
    # A variável FORCE serve para forçar uma "atualização do ip, uma vês que um domínio torna-se inexistente apos 2h sem atualização
    # A variável FORCE recebe o primeiro parâmetro passado ao programa, se esse for "yes" o ip sera forçado a 0.0.0.0
    FORCE="$1"

    # Caso o domínio, a senha ou ambos estiverem vazios
    if [ "$DOMINIO" == "" ] || [ "$SENHA" == "" ];then
    echo "É necessários setar as variáveis DOMINIO e SENHA"
    exit
    fi


    main(){
    # Caso tenha sido passado o yes é forçada a atualização do ip
    if [ "$FORCE" == "yes" ];then
    echo "0.0.0.0" > ${TMPDIR}/ddns.ip
    exit
    fi

    # Se o arquivo ${TMPDIR}/ddns.ip não existe, cria-lo com 0.0.0.0
    if [ ! -e ${TMPDIR}/ddns.ip ]
    then
    echo "0.0.0.0" > ${TMPDIR}/ddns.ip
    fi

    # Se a variável IP não tiver sido setada no inicio desse script a função getip será chamada para descobrir o ip, caso ela tenha sido setada o ip será atribuído diretamente
    if [ "$IP" == "" ];then
    getip
    else
    echo "$IP" > ${TMPDIR}/ddns.ip.new
    fi

    # Comparamos para ver se o ip realmente mudou
    if [ `cat ${TMPDIR}/ddns.ip.new` != `cat ${TMPDIR}/ddns.ip` ]; then
    # Trocamos o arquivo base pelo novo IP
    mv ${TMPDIR}/ddns.ip.new ${TMPDIR}/ddns.ip
    NEWIP=`cat ${TMPDIR}/ddns.ip`
    # Setamos o DDNS com o novo IP
    ${BINDIR}/ddnsquery -t SET -a $NEWIP -p $SENHA $DOMINIO
    fi
    }


    getip(){
    unset LANG
    # Se no arquivo ddns.sh o nat estiver como yes o if será executado, se estiver como no será o else
    if [ "$NAT" == "yes" ];then
    # baixa o index de "www.qualemeuip.com.br" ou o ip.php setado em NATIP que contem o ip real de internet.
    # -T 20 diz que não pode levar mais de 20 segundos para baixar o arquivo
    # -t 2 diz que serão feitas no máximo duas tentativas em caso de falha
    # -nc diz que se o arquivo já existir ele será substituído e não renomeado para *.1
    # -O meuip diz que o nome do html baixado será "meuip"

    if [ "$NATIP" != "" ];then
    /usr/bin/wget -T 20 -t 2 -nc -q -O meuip "$NATIP"
    # Lê o arquivo meuip e devolve apenas o ip
    cat meuip > ${TMPDIR}/ddns.ip.new
    else
    /usr/bin/wget -T 20 -t 2 -nc -q -O meuip $QUALEMEUIP
    # Lê o arquivo meuip faz filtragens e devolve apenas o ip
    cat meuip |grep "^<title>" |awk -F '</' '{print $1}' |awk -F ' ' '{print $5}' > ${TMPDIR}/ddns.ip.new
    fi

    # remove o arquivo meuip
    rm -rf meuip
    else
    # Captura o endereço ip a da interface definida na variável INTERFACE
    /sbin/ifconfig $INTERFACE | grep -i "inet " | cut -d: -f2 | cut -d" " -f1 > ${TMPDIR}/ddns.ip.new
    fi
    }

    main

    CONTINUA.......
    Última edição por landrower; 23-04-2009 às 17:43.

  2. #2

    Post

    CONTINUANDO....

    Agora baixe o e descompacte o cliente linux do DDNS em:
    Downloads | DDNS - Winco Tecnologia e Sistemas


    Em seguida descompacte o arquivo e copie apenas o executável ddnsquery para /usr/local/sbin/ddnsquery, certifique-se que ele tenha permissão de execução
    Também é necessário criar duas entradas na cron para que esse script seja executado periodicamente, as entradas deverão ser colocadas em /etc/crond.d/ddns
    Seguem as crons:


    0-59/2 * * * * root /usr/local/sbin/ddns.sh
    00 * * * * root sleep 30 ; /usr/local/sbin/ddns.sh yes


    A primeira diz para executar o ddns.sh a cada 2 min, serve para verificar se o ip mudou e caso positivo atualiza-lo no ddns.com.br
    A segunda diz para executar o ddns.sh com o parâmetro yes a cada hora e trinta segundos, os 30 segundos são com intenção de as crons não serem executadas simultaneamente. Essa serve para forçar uma “mudança” de ip, uma vês que se passar 2 horas sem o servidor contatar o ddns.com.br o domínio expira.


    Feito isso agora é necessário dar um restart na cron.


    Ultimo passo:
    Caso o domínio utilizado seja novo, será necessário baixar o cliente windows e configura-lo uma única vêz com o domínio e a respectiva senha para “ativa-lo” uma vês que a versão linux não consegue fazer essa primeira ativação, após feito se o domínio configurado já estiver respondendo, desista-le a versão windows.
    O cliente windows pode ser instalado em qualquer maquina em qualquer lugar, não precisa necessariamente estar na mesma rede, podendo você pedir para algum amigo faze-lo pra vc caso não tenha uma maquina windows disponível.
    O cliente windows pode ser baixado em:
    DDNS Dynamic Domain Name System - Winco Tecnologia e Sistemas


    Feito isso na próxima execução da cron o ip já será atualizado pelo linux.


    O tutorial de instalação para linux feito pela própria ddns.com.br encontra-se em:
    DDNS Dynamic Domain Name System | Como configurar o DDNS para Linux - Winco Tecnologia e Sistemas
    Mas esse é praticamente inútil.


    Quem quiser entender os problemas que encontrei na versão linux do ddns pode ler abaixo o e-mail que enviei para a ddns.com.br


    No mais é isso galera, espero que este artigo ajude outras pessoas.


    Abraços


    E-mail à ddns.com.br:


    Boa noite.
    Quero antes de mais nada dar os parabéns pela iniciativa de vocês de fornecerem gratuitamente esse serviço de ddns que é muito útil para vários usuários.

    Minha intenção ao enviar-lhes este e-mail é relatar problemas que encontrei na versão linux do softwares DDNS e contribuir com o projeto DDNS em nome da empresa ProSolution atuante no mercado de TI.

    Eu, Lawrence, Administrador de redes da Prosolution trabalho diretamente com linux e infelizmente tenho que dizer que a versão linux do DDNS deixa muito a desejar, bem na real ela não funciona e possui varias incoerências na lógica de programação, além de não suportar o caso de a maquina em questão possuir ip dinâmico e estar atrás de um router(NAT) que é sem duvidas o caso mais comum.
    Eu precisei usar o serviço DDNS de vocês e acabei descobrindo os problemas do software e modifiquei-o de forma que ele passou a funcionar com o caso de ip dinâmico + nat, além consertar erros na logica de programação dos scripts ".sh"

    Problemas encontrados:
    1) Não suporta ip dinâmico + nat
    Resolvido.

    2) Erro de logica de programação no ddns.sh
    Dado o codigo:
    if [ $? -ne 0 ]
    then
    echo "0.0.0.0" > ${TMPDIR}/ddns.ip #isso vai forcar refresh
    fi

    Isso diz que se o ultimo comando executado não tiver sido executado com exito deverá ser escrito 0.0.0.0 dentro do arquivo /tmp/ddns.ip
    Isso não faz sentido, não tem porque forçar um refresh se o ultimo comando foi exatamente o que deveria ter descoberto o novo ip e não conseguiu faze-lo. Isso é totalmente desnecessário e foi removido do código.
    Resolvido.

    3) Erro de logica de programação no arquivo ddns-refresh.sh
    O tutorial de instalação diz para agendar ele pra rodar a cada 30 segundos, o que ele faz é a mesma coisa que o trecho citado no item 2, ele escreve o ip invalido 0.0.0.0 no arquivo /tmp/ddns.ip a cada 30 segundos, dessa forma mesmo que o ip da maquina não tenha mudado o computador vai conectar-se no servidor do DDNS para "atualizar" o ip, gerando carga desnecessária no servidor de vocês, uma vês que que a atualização só seria necessária caso o ip tivesse mudado ou a cada 2h que é o tempo máximo que o servidor de vcs mantém o registro DNS valido sem uma atualização.
    Cron agendada para rodar a cada hora e trinta segundos(os trinta segundos são para que duas instancias não sejam chamadas simultaneamente.)
    Resolvido.

    4) Erro de logica de programação no arquivo ddnsfixo-refresh.sh (GRAVE!)
    Dado o código:
    # As seguintes variáveis devem ser configuradas:
    #
    DOMINIO="" #Seu end. DDNS (ex.: meuendereco.ddns.com.br)
    SENHA="" #A sua senha para o dom.nio
    IP="" #Coloque aqui o endereco IP.
    # Ex.: ppoe, eth0, etc
    ##################################################
    BINDIR=/usr/local/sbin
    ##################################################

    ${BINDIR}/setdns $SENHA $DOMINIO $IP
    while [ $? -ne 0 ]
    do
    ${BINDIR}/setdns $SENHA $DOMINIO $IP
    done


    Esse while ai diz que enquanto o resultado do comando "${BINDIR}/setdns $SENHA $DOMINIO $IP" não der certo ele vai ficar executando-o seguidamente sem intervalos até que ele de certo.
    No tutorial vocês dizem que é para colocar ele para ser executado automaticamente a cada 30 segundos, bem, se o link de internet desse cliente cair e o comando citado der errado o processo não vai morrer pois está preso num laço que depende de o ultimo comando dar certo, pior ainda, como está agendado para ser executado de 30 em 30 segundos, a cada 30 segundos ira ser aberto um novo processo, dessa forma a cada hora que a link permanecer fora serão abertos 120 processos, no fim ou a maquina vai travar ou se o link voltar depois de 4h por exemplo.. a maquina do cliente ira mandar simultaneamente 480 pedidos de atualização ao servidor do DDNS.
    Imaginem então se o link da uma operadora cair por essas mesmas 4h e ela tiver digamos uns 5.000 clientes que usam o ddns de vcs, quando a operadora normalizar suas operações vcs vão receber 2400000(dois milhões e quatrocentos mil) pedidos simultâneos de atualizações, o servidor de vcs vai simplesmente travar por negação de serviço.

    Bem, esse arquivo foi feito para o caso de o ip ser fixo e o ip é setado nesse próprio arquivo na variável "IP", além desse arquivo ser uma bomba de erros de programação ele não faz sentido nenhum, pois se o ip é fixo e setado no próprio arquivo, qual a razão de se mandar atualizações de 30 em 30 segundos ao servidor do DDNS?????

    Nesse caso o while foi deletado, a execução automática desse script foi agendada para cada uma hora.
    Resolvido.

    Antes de irmos ao 5° problema quero dizer que todos os problemas anteriores foram resolvidos e os 5 scripts (ddns.sh ddns-refresh.sh getip.sh ddnsfixo-refresh.sh e setdns.sh) foram transformados em apenas um ddns.sh, que no caso de ip dinâmico pode ser agendado para executar de 1 em 1 minuto(ou qualquer outro tempo desejado) e no caso de ip fixo de hora em hora.
    Isso tudo + o esquema de implementar o caso de ip dinâmico + nat.

    5) Problema na programação do ddnsquery
    Esse problema eu não consegui resolver pois o arquivo é um binário e vcs não disponibilizam os fontes, porém ao identificar o problema consegui contorna-lo.
    O caso é que apos criar um novo domínio exlawrence.ddns.com.br) receber a senha e configurar os arquivos do ddns, ao tentar executa-lo para que ele atualize o ip fazendo com que o nome lawrence.ddns.com.br tenha um ip atribuido, o ddnsquery dá o erro:
    ; flags: 8503
    Nome não Encontrado


    Quando percebi esse erro fiquei ouvindo na rede o que o programa estava fazendo e descobri que a primeira coisa que ele faz é peguntar ao servidor DNS de vcs "201.49.222.150"(ddns-ns2.winco.com.br) quem é o "lawrence.ddns.com.br" e o servidor diz que esse nome não existe.
    O nome não existe mesmo, ou ao menos não tem um ip atrelado a ele, até porque é exatamente o que esse programa deveria fazer.
    Bom, apos o programa receber do servidor a resposta que o nome não existe ele simplesmente dá erro e sai, dessa forma o programa nunca teria como funcionar.
    Nos testes que vocês devem ter feito ai, esse problema não deve ter sido detectado porque vcs provavelmente testaram com um nome que já estava previamente configurado, dessa forma o problema passou despercebido.
    Bom, a maneira que arrumei de contornar o problema foi instalar o ddns para windows configura-lo e executa-lo uma vez para ele "ativar" o nome lawrence.ddns.com.br, e em seguida desinstala-lo, apos isso o programa de linux consegue atualizar o ip.

    Aki temos 2 soluções para o caso, uma é arrumarem esse ddnsquery para que ele faça o mesmo trabalho que sua versão para windows, ou quando um novo sub-dominio for criado esse já deverá ser ativado com um ip qualquer que pode até apontar para a própria pagina de vcs.

    Podemos enviar o programa a vocês já todo arrumado menos o ítem 5(que depende de vcs) sem custo nenhum, apenas peço que deixem uma referencia(dentro do arquivo ddns.sh) ao nome da empresa XXXX como colaboradora do projeto.

    Att,
    Lawrence