Utiliser l’API OVH pour se faire un dyndns maison

Il se trouve que j’ai un des  serveurs à la maison, derrière une connexion grand public, à adresse IP variable.
Cela signifie que dès que le routeur est redémarré ou perd sa connexion, je risque de changer d’adresse IP et mes enregistrement DNS vers mamaison.e-jim.be ne seront plus valables et cela m’empêchera de me connecter à mon serveur.

J’ai donc mis en place un petit script PHP que mon serveur vient déclencher toutes les heures (tâche cron).
Voici comment j’ai procédé, si jamais ça peut servir à quelqu’un.

1. Obtenir les clefs d’application/d’utilisateur

Depuis la mise en place de leur API RESTful (remplaçant une API SoAP), OVH ne permet plus de ce connecter directement avec ses identifiants OVH, mais uniquement avec des tokens pré-générés, à l’aide desquels on pourra signer les requêtes faite via l’API.

Pour générer un token pour votre script, rendez-vous sur https://eu.api.ovh.com/createToken/ et remplissez le formulaire avec votre identifiant OVH, votre mot de passe, le nom du script et sa description.
Vous devrez également préciser la durée de validité des tokens et les autorisations qu’ils portent:
Dans les autorisation, j’ai donné au script les droits de lecture (GET), écriture (POST), modification (PUT) et suppression (DELETE) sur tous mes domaines (donc au chemin /domain*).

Création de token + Autorisations
Création de token + Autorisations

 

La réponse à la requête
La réponse à la requête

2. Obtenir l’ID du record DNS à modifier

La requête devant être passée avec l’ID de l’enregistrement DNS, il faut obtenir cette valeur avant de faire les changements.
On peut l’obtenir en faisant une requête GET sur https://eu.api.ovh.com/1.0/domain/zone/NOMDEVOTREZONE/record?subDomain=SOUSDOMAINE, en remplaçant NOMDEVOTREZONE et SOUSDOMAINE par les valeurs qui correspondent à votre cas (pour moi, e-jim.be et mamaison, respectivement).

On peut aussi faire cette requête manuellement sur https://api.ovh.com/console , ce que j’ai fait parce que je n’avais qu’un sous-domaine à traiter et que l’ID de l’enregistrement ne va jamais changer (sauf à le supprimer et le re-créer).

3. Le script à proprement parler

Et voilà le script que j’utilise. Il est donc placé sur un serveur extérieur et appelé par mon serveur-maison chaque heure.
Notez que je ne suis pas dev et donc j’ai fait quelques trucs pas très propres grâce à la méthode La , j’en ai conscience:

  • tout est en procédural
  • au lieu d’utiliser l’extension curl de php, dont je ne connaissais pas l’existence, je fais un exec sur le curl du système et utilise le retour du shell. Niveau performance, ça doit être dégueu. Mais pour un script appelé une fois par heure, l’impact est nul.
  • mes variable et fonctions sont nommées sans suivre la moindre constance (parfois en français, parfois en anglais, parfois en CamelCase, parfois pas, etc…)
  • il est peu flexible/générique

En cas de changement d’IP, il enverra un mail avec l’ancienne et le nouvelle ip à l’adresse VOTRE_MAIL indiquée à la ligne 71.

 

//L'ID du record peut être obtenu en faisant une requête GET sur https://eu.api.ovh.com/1.0/domain/zone/NOMDEVOTREZONE/record?subDomain=SOUSDOMAINE
//On peut aussi faire cette requête manuellement sur https://api.ovh.com/console


//fonction pour les requêtes vers l'API. Par défaut, elle demande les infos sur le sous-domaine (TTL, target, Type d'enregistrement,...). Modifier pour mettre votre ID comme décrit ci-dessus

function requeteAPIOVH($url = "https://eu.api.ovh.com/1.0/domain/zone/NOM_DE_VOTRE_ZONE/record/ID_DE_VOTRE_ENREGISTREMENT", $action = "GET", $data="")



{

	$applicationKey="DONNEES_OBTENUES_AU_POINT_1";
	$applicationSecret="DONNEES_OBTENUES_AU_POINT_1";
	$ConsumerKey="DONNEES_OBTENUES_AU_POINT_1";
	$endpoint_name="DNS-Change3";


	$timestamp=time();
	$prehash=$applicationSecret."+".$ConsumerKey."+".$action."+".$url."++".$timestamp;
	$hash=sha1($prehash);
	$signature="$1$".$hash;

	$options_Curl=" -H 'X-Ovh-Application:".$applicationKey."'";
	$options_Curl.=" -H 'X-Ovh-Timestamp:".$timestamp."'";
	$options_Curl.=" -H 'X-Ovh-Signature:".$signature."'";
	$options_Curl.=" -H 'X-Ovh-Consumer:".$ConsumerKey."'";
	$options_Curl.=" ".$url;

	if ($action == "GET")
	{
		$commande="curl ".$options_Curl;
	}
	elseif ($action == "PUT")
	{
		$commande="curl -X PUT -d ".$data." ".$options_Curl;
		print_r($commande);
	}

        elseif ($action == "POST")
        {
            if ($data == "")
                {
                $commande="curl -X POST ".$options_Curl;
                print_r($commande);
                }
            else
                {
                $commande="curl -X POST -d ".$data." ".$options_Curl;
                print_r($commande);
                }
    }

	$output=array(); /juste pour éviter les warning du parser PHP
	exec($commande, $output);

	$resultat=json_decode($output[0], true);
	print_r($resultat);
	return $resultat;
}


if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
    $IP = $_SERVER['HTTP_X_FORWARDED_FOR'];
    elseif(isset($_SERVER['HTTP_CLIENT_IP']))
    $IP = $_SERVER['HTTP_CLIENT_IP'];
    else
    $IP = $_SERVER['REMOTE_ADDR'];

echo "IP = ".$IP.". Et puis c'est tout\r\n";

$OLD_IP =requeteAPIOVH()['target'];
echo "L'ancienne IP était ".$OLD_IP;


if ($IP == $OLD_IP)
{
echo " \r\nL'ip n'a pas change.";
}
else {
    echo "\r\nL'IP a change";
    mail("VOTRE-MAIL","L'IP de la maison a changé","info du script IP maison\r\nIP était:".$OLD_IP."\r\nIP est:".$IP);

	requeteAPIOVH ("https://eu.api.ovh.com/1.0/domain/zone/NOM_DE_VOTRE_ZONE/record/ID_DE_VOTRE_ENGISTREMENT", "PUT", "target=".$IP);
        requeteAPIOVH ("https://eu.api.ovh.com/1.0/domain/zone/e-jim.be/refresh", "POST");
	echo "\r\nL'IP a été modifiée dans le DNS";
}

exit(0);

Le tout est sauvé sur un script sur mon serveur web extérieur, sous un nom cryptique pour éviter qu’il ne soit appelé par erreur. (oui, il existe d’autre solutions, mais ça me suffit comme « sécurité »).

Côté maison

J’ai cette ligne dans cron:

0 * * * * /usr/bin/curl https://e-jim.be/NOM_DE_MON_SCRIPT.php

et c’est tout.

2 Comments