Créer un outil de type « Mon adresse IP »
Je me demandais comment des outils de type « Mon adresse IP » peuvent obtenir à la fois l'adresse IPv4 et IPv6 de l'utilisateur alors qu'une requête web est, par définition, effectuée à partir d'une seule adresse.
Il s'avère que cela s'appuie sur une astuce tout simple : une fois la page chargée, des requêtes sont effectuées via JavaScript vers des services Web qui ne répondent que sur IPv4 ou IPv6. Cela est à son tour facilité par le fait qu'il est possible de configurer Nginx pour renvoyer un objet JSON avec ces informations sans utiliser aucun backend.
J'ai trouvé des explications sur le web sur la façon d'en faire certaines parties, mais pas la totalité, je fais donc cette page pour expliquer comment créer un tel outil avec Nginx et du JS vanilla.
Configuration DNS
La première étape consiste à configurer un nom de domaine afin que certains sous-domaines ne soient accessibles que via IPv4 ou IPv6. Voici ce que j'ai fait pour le domaine ash.bzh :
ip 1800 IN A 54.37.75.168 ip 10800 IN AAAA 2001:41d0:701:1100::3ec ipv4 1800 IN A 54.37.75.168 ipv6 10800 IN AAAA 2001:41d0:701:1100::3ec
Le sous-domaine ip.ash.bzh
peut répondre avec les deux versions, tandis que ipv4.ash.bzh
ne peut être atteint que via IPv4 et ipv6.ash.bzh
via IPv6.
Configuration Nginx
La configuration Nginx côté serveur est également très simple à configurer :
# /etc/nginx/sites-available/ip.conf server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name ip.ash.bzh ipv4.ash.bzh ipv6.ash.bzh; location / { add_header Access-Control-Allow-Origin *; default_type application/json; return 200 "{\"ip\":\"$remote_addr\"}"; } # [...] }
Ici, tout chemin sur l'un des trois sous-domaines renverra la même chose : un fichier JSON bien formaté et compatible CORS avec une clé ip
et l'adresse IP utilisée pour la requête comme valeur.
HTML
Maintenant, pour la page destinée à l'utilisateur, tout ce dont il y a besoin est un appel à un fichier Javascript qui contiendra toute la logique, et un tableau HTML où les requêtes JS ajouteront leurs résultats :
<!-- ip.html --> <!-- [...] --> <table id="ip-info"> <caption>IP info</caption> <tbody> </tbody> </table> <script src="/static/js/ip.js"></script> <!-- [...] -->
Javascript
Le script lui-même est également très simple :
- Une fonction
pingIP
est appelée deux fois, avec le nom de chaque version du protocole utilisée en paramètre. Elle récupère le fichier JSON, extrait l'adresse IP et la transmet à la fonctionaddRow
. - La fonction
addRow
transforme les données en une ligne de tableau et les insère dans le tableau HTML.
// static/js/ip.js function addRow(protocol, ip) { let tbody = document.getElementById('ip-info').getElementsByTagName('tbody')[0]; let new_row = tbody.insertRow(); new_row.outerHTML = `<tr><th>${protocol}</th><td>${ip}</td></tr>` } function pingIP(protocol) { let url = `https://${protocol.toLowerCase()}.ash.bzh/`; fetch(url, { headers: { 'Accept': 'application/json' } }) .then(response => response.json()) .then(json => addRow(protocol, json.ip)) } pingIP('IPv4'); pingIP('IPv6');
Et c'est à peu près tout !
Vous pouvez voir le résultat sur https://tools.ash.bzh/fr/tools/ip/
Image d’en-tête:
Photo d’un panneau d’affichage de gare avec des données de diagnostic, y compris un adresse IP, prise à la gare de Hawarden, Flintshire, Pays de Galles. CC-BY-SA 3.0 Rept0n1x.