Skip to content
September 7, 2010 / ftth

Mise à jour dyndns automatique avec OVH et une NeufBox sous Debian

L’adresse IP de mon FAI (SFR) changeant régulièrement, je voulais utiliser dyndns. Seul problème, le seul service de DynDNS supporté dans la NeufBox est dyndns.org. Je n’ai rien de particulier contre ce service, sinon qu’il requiert de l’utilisateur de se logguer régulièrement dans le site pour ne pas voir sa redirection expirer (version gratuite).

Ayant un domaine chez OVH, j’ai découvert qu’il était possible de profiter d’un service similaire, mais les instructions fournies par l’hébergeur étaient plutôt floues, et basées sur le script ipcheck.py via l’utilisation d’un script bash et d’un fichier texte pas très ragoûtants.

J’ai donc fini par réaliser un script en python inspiré de ipcheck.py qui réalise:

  • la détection de l’adresse IP courante auprès de la NeufBox en utilisant son API REST (plus particulièrement, ppp.getInfo)
  • la résolution de mon hôte dyndns en utilisant socket.gethostbyname pour la comparer avec l’IP réelle (pour éviter des mises à jour superflues)
  • le cas échéant, la mise à jour de l’IP associée à l’hôte dyndns

Code source:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from urllib import urlopen
from commands import getoutput
from socket import gethostbyname
import httplib
import base64
import sys

HOST = 'myhost.mydomain.org'
LOGIN = 'logindyndnsovh'
PASSWORD = 'hackme'
PROVIDER = 'www.ovh.com'
USER_AGENT = 'unkown'
ROUTER_IP = '192.168.1.1'
ROUTER_URL = 'http://%s/api/?method=ppp.getInfo' %ROUTER_IP

def parse_ip():
    print 'Checking for public IP on router', ROUTER_IP
    conn = urlopen(ROUTER_URL)
    data = conn.read()
    conn.close()
    import re
    pattern =  r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
    try:
        ip = re.search(pattern, data).group()
    except Exception:
        ip = None
    return ip

def update_ip(ip):
    url_suffix = '/nic/update?system=dyndns&hostname=%s&myip=%s&wildcard=OFF&backmx=NO' %(HOST, ip)
    h = httplib.HTTP(PROVIDER)
    h.putrequest("GET", url_suffix)
    h.putheader("HOST", PROVIDER)
    h.putheader("USER-AGENT", USER_AGENT)
    authstring = base64.encodestring(LOGIN + ":" + PASSWORD)
    authstring = authstring.replace("12", "")
    h.putheader("AUTHORIZATION", "Basic " + authstring)
    h.endheaders()
    errcode, errmsg, headers = h.getreply()
    if errmsg == 'OK':
        print 'Update completed fine, exiting'
        sys.exit()
    else:
        print 'WARNING, dynamic update could not be completed', errcode, errmsg
        sys.exit(1)

if __name__ == '__main__':
    try:
        ip = parse_ip()
        if ip is None:
            print 'Error, found no IP from router, exiting'
            sys.exit(1)
        old_ip = gethostbyname(HOST)
        if ip == old_ip:
            print 'No change, doing nothing'
            sys.exit()
        else:
            print 'Trying to update IP at', PROVIDER
            update_ip(ip)
    except Exception, e:
        print 'Unkown error occured', e
        sys.exit(1)
Vous pouvez télécharger le script ici (mais il est nécessaire de le renommer en .py car WordPress n’accepte ni les pièces jointes en .py ou .txt ….)
Il suffit ensuite de placer le script dans un chemin accessible par le PATH, lui donner les droits d’exécution, et enfin d’ajouter un job cron:
sudo cp dyndns_update.py /usr/local/bin/dydns_update.py
sudo chmod +x /usr/local/bin/dyndns_update.py
user@machine:~$crontab -e
00 4 * * *   /usr/local/bin/ovh_neufbox_dyndns.py
Le script se lance alors tous les jours à 4h, et le résultat de l’opération est notifié par email sur le compte local (debian).

6 Comments

Leave a Comment
  1. François / May 12 2011 6:52 pm

    Bonjour,

    Ceci ne pose-t-il pas des problèmes de propagation de DNS fréquent, rendant la redirection inutilisable assez fréquemment ?

    • ftth / Feb 25 2014 10:22 am

      Je dirais que cela dépend si votre IP publique change souvent 🙂

  2. ftth / May 29 2011 8:43 pm

    Effectivement, il y a un downtime théorique lié à la vitesse de propagation DNS en cas de changement d’adresse publique.

    Le script fonctionnant la nuit, je n’ai cependant en pratique pas encore rencontré le problème.

  3. François / Jun 4 2011 7:42 pm

    Merci beaucoup de votre réponse.

  4. Axel / Dec 7 2012 8:33 pm

    Hello, merci pour le script. J’ai un petit problème: mon domaine principal est domain.com. J’aimerais faire un dynhost sur home.domain.com. Seulement, pour simplifier le réseau interne, j’ai ajouté une entrée dans le DNS de la neufbox:
    home.domain.com => 192.168.1.2
    Du coup, l’appel python gethostbyname retourne 192.168.1.2 car il se base sur le DNS de l’ordi (donc celui de la neufbox). Donc, il met à jour systématiquement l’IP sur OVH. C’est pas très grave en soi, c’est juste pour éviter de faire un update du dyndns à chaque exécution du script.
    J’ai pas trouvé comment forcer gethostbyname à changer de DNS.

    Merci en tous les cas

    Axel

Trackbacks

  1. Linux distros for AMD Geode LX800 CPU « Video/Linux Facts and Hacks

Leave a reply to ftth Cancel reply