Les portails captifs …

Avant de commencer, je tiens à préciser que ce billet sera forcement incomplet. En effet, il existe une multitude de portails captifs en circulation et je n'ai pas la prétention de tous les connaître ni de faire un billet qui les concerne tous. Sans compter les configurations qui varient d'un intégrateur à un autre pour un même produit ... Dans ce billet, je vais vous donner les bases, des pistes de recherche et rien de plus. Ne soyez donc pas déçus.

Ha ! Les portails captifs ! Entre ceux qui les croient indétrônables et les mettent en place sans d'autres mesures complémentaires de sécurité et de bon sens et ceux qui passent leur temps à pester contre eux lorsqu'ils les empêchent de faire des actions légitimes ...

Dans ce billet, je parlerai des portails captifs que l'on trouve sur les accès WiFi "ouverts" comme des portails captifs que l'on trouve sur des connexions filaires. Leurs principes de fonctionnement sont identiques.

Table des matières

Contourner un portail captif

Je sais que les poils de certains lecteurs se sont hérissés à la lecture du mot "contourner". Bah oui, contourner un portail captif c'est forcement dans une mauvaise intention. Bah non ... On peut contourner un portail captif pour des raisons légitimes. Au pif : vous attendez toujours votre identifiant alors que vous avez payé il y a déjà longtemps votre accès à internet ou bien le portail captif déconne une fois de plus et vous avez besoin de vous informer, de vous divertir, de communiquer rapidement, ou que sais-je.

Plusieurs méthodes de contournement (= accéder à internet sans identifiant) sont possibles, parmi lesquelles :

  • Pinger une machine du réseau et dès qu'elle ne répond plus, on peut considérer que son propriétaire l'a éteinte sans pour autant prendre le temps de se déconnecter du portail captif. Il suffit donc de prendre l'adresse IP de cette machine et vous serez authentifié. Sisi, une technique aussi basique fonctionne encore en 2011 (à qui la faute ?) !
  • Pour les portails captifs un peu plus exigeants, il suffira d'usurper l'adresse MAC en même temps que l'adresse IP. Un ping puis un arp -a suffira à découvrir l'association entre adresse IP et adresse MAC sans utiliser d'analyseur réseau (vous savez, des logiciels comme tcpdump ou wireshark). Cette usurpation peut même avoir lieu pendant que la victime est connectée.
  • Normalement, tous les ports sont verrouillés tant que le client ne s'est pas authentifié. Mais parfois, on trouve des portails captifs avec des ports standards ouverts. Il suffit d'héberger, en dehors du réseau, un serveur (SSH/OpenVPN si c'est un port TCP qui est ouvert, OpenVPN pour un port UDP) et de faire du tunneling. Ex. : si vous constatez que le port 53/UDP est ouvert, montez un serveur OpenVPN sur le port 53/UDP. Attention toutefois à ce que le trafic ne soit pas dirigé vers une destination précise (ex. : le port 53/UDP est ouvert, mais le trafic sur ce port est dirigé vers un vrai résolveur DNS qui ne laissera pas passer votre connexion VPN). Ce genre de manipulation peut être démasquée en regardant le TTL des réponses. Si le paquet de retour a un TTL de 1, 2 ou une valeur faible, le serveur est tout près et il ne s'agit probablement pas du serveur que vous cherchez à atteindre.
  • Si aucun port n'est ouvert ou si le trafic est redirigé vers une machine particulière, il vous reste le tunneling plus avancé : TCP over ICMP, TCP over DNS, etc. De mon expérience, si le protocole ICMP est souvent bloqué, le protocole DNS n'est jamais bloqué afin de permettre la redirection du navigateur vers la page d'authentification (votre navigateur cherchera à résoudre google.fr, par exemple. S'il n'y parvient pas, il n'enverra pas de message HTTP et la passerelle ne pourra donc pas le rediriger vers la page d'authentification). Parmi les logiciels utilisables, on peut citer iodine (mon préféré), heyoka, ozymanDNS, dnstunnel ... Je vous propose ce site : Le Blog du grand loup Zeur comme tutoriel. Attention toutefois : ce genre de tunneling n'est pas le plus efficace qui soit en terme de débit (pour avoir essayé ...). De plus, vous pouvez facilement être détecté par une analyse volumétrique du trafic dû au flot inhabituel que vous allez générer sur le service choisi (ex. : DNS). À noter que ce type de tunneling permet aussi de passer les firewalls qui inspectent le contenu des paquets pour vérifier qu'ils sont conformes aux spécifications du protocole auxquels ils prétendent appartenir (ex. : iodine passera très bien un l7-filter configuré pour ne laisser passer que le protocole DNS sur le port UDP/53).
  • À l'aide d'un "complice" ayant une machine authentifiée sur le réseau, il suffit d'utiliser le NAT. Le concept est simple : sa machine est authentifiée et va transmettre vos paquets sous son identité. Vous allez peut-être vous dire qu'il faut donc que votre complice ait une machine avec deux cartes réseau ou qu'il vous faut un commutateur. Que nenni ! Vous vous raccordez sur le même réseau, via les prises murales ou que sais-je. Sur le serveur (la machine de votre "complice"), vous passerez en IP fixe (en utilisant évidemment une IP routable sur le réseau, c'est-à-dire une IP appartenant au même réseau que la passerelle), vous activez l'ip forwarding et le NAT. Pour accroître un peu la sécurité, le serveur ne NATera que les paquets dont l'IP source est celle de votre machine (le client). Ceci est à configurer dans la chaîne FORWARD pour les iptabliens. Cela évite que quelqu'un d'autre, par hasard, comprenne le truc et utilise aussi le serveur sans votre accord. Sur le client, il suffit de passer en IP fixe (= pas de DHCP), de déclarer le serveur comme route par défaut et en avant ! Cette technique peut également vous servir si vous avez deux machines vous appartenant pour un seul identifiant. Si en plus vous avez deux machines pour une seule prise murale, alors là oui, vous aurez besoin d'un commutateur.
  • ...

S'authentifier automatiquement sur un portail captif

Il n'y a rien de plus embêtant que de devoir se connecter à chaque fois au portail captif. Pour éviter ce calvaire, il suffit d'utiliser curl (mon préféré) ou wget pour qu'ils vous connectent automatiquement.

Il suffit d'analyser le code source de la page d'authentification et notamment les paramètres passés via l'URL ou via un formulaire. Méfiez-vous des champs cachés qui doivent tout de même être remplis ! Faites également attention aux pages qui s'enchainent (ex. : une page vous demande votre login, puis une page qui vous demande votre mot de passe, seule la deuxième page est importante). Il suffit ensuite de créer une commande curl qui remplira le formulaire pour vous et vous connectera automatiquement.

Par exemple, si la page d'authentification ressemble à ça (exemple inventé) et se trouve sur le serveur 10.123.36.254) :

<form method="post" action="fin.html">
	<input type="hidden" name="url" value=""/>

	<input type="hidden" name="meth" value="radius"/>
	<input type="hidden" name="action" value="login"/>

	<input type="hidden" name="time" value="360"/>
	<input type="password" name="pswd" size="25"/>

	<input type="hidden" name="uid" value="mon_login"/>
 
	<input type="submit" value="OK">

	<input type="button" value="Annuler" onclick="window.location='/';">
</form>

Alors la commande curl correspondante ressemblera à :

curl -m 5 -d pswd=votre_mdp -d uid=mon_login -d time=360 -d url= -d meth=radius -d action=login "http://10.123.36.254/fin.html" > /dev/null 2>&1

Le paramètre "-d" permet de remplir les champs, "-m 5" demande à curl d'arrêter sa tentative de connexion après 5 secondes.
À vous d'adapter ceci à votre situation. Exemple : si votre portail captif utilise le protocole HTTPS et un certificat non valable, utilisez l'option "-k" de curl pour contourner ce problème.

Il ne vous reste plus qu'à mettre cette commande dans un script shell, de le rendre exécutable et d'utiliser le Network Manager ou bien Wicd (Propriété de la connexion, Scripts, Exécuter un script après connexion) ou le fichier de configuration /etc/network/interfaces et son paramètre "post-up" pour exécuter le script dès la connexion au réseau et ainsi être authentifié automatiquement.

Maintenir l'authentification

Il n'y a rien de plus chiant que d'interrompre une séance productive de travail pour se reconnecter, car le timeout du portail captif a expiré ! Le pire, c'est quand le timeout est démesurément court : 30 minutes, par exemple (sisi, j'ai déjà vu ça !).

La solution est simple, il suffit d'utiliser cron pour lancer le script d'autoconnexion écrit ci-dessus à un intervalle régulier. Pour cela, il suffit d'utiliser la commande :

crontab -e

Et de rajouter une ligne. Par exemple (le script sera lancé toutes les 5 heures) :

* */5 * * * /home/guigui/.autoconnect

Astuces bonus

Il arrive que le portail captif refuse de vous identifier alors que vous avez fourni les bons identifiants. Deux causes peuvent expliquer cela : le fait que le serveur DHCP vous ai attribué une autre IP (lors d'une demande post-reboot ou lors d'un renouvellement) et la cause inconnue.

Dans le premier cas, il suffit de reprendre votre ancienne IP et si vous le souhaitez, de vous déconnecter du portail, de reprendre l'IP qui vous a été attribué en dernier et vous authentifier. Le problème étant de connaître son avant-dernière IP. La commande suivante devrait vous aider à connaître les 2 dernières IPs qui vous ont été attribuées :

sudo grep "dhclient: bound to" /var/log/daemon.log | tail -2

Dans le deuxième cas, j'ai constaté que ce problème se résout en envoyant plusieurs requêtes d'authentification au portail captif. Il suffit donc de répéter la commande d'autoconnexion plusieurs fois. Par exemple :

#!/bin/bash
 
while let 1; 
do 
	curl -d pswd=votre_mdp -d uid=mon_login -d time=360 -d url= -d meth=radius -d action=login "http://10.123.36.254/fin.html";

done

Vous vous apercevrez que le portail va très rapidement (dans les 30 secondes) vous authentifier puis repartir en erreur. Mais ce n’est pas grave : vous serez authentifié ! Contrairement aux apparences, ce script n'est pas une boucle infinie destructrice : un simple CTRL+C suffit pour tout arrêter). Faites quand même attention lorsque vous l'employez afin que l'on ne vous accuse pas de porter atteinte à un système automatisé de traitement de données alors que vous cherchez simplement à rétablir un service légitime. C'est la mode ces temps-ci ...

Se déconnecter automatiquement (ÉDIT du 03/04/2012 à 18h15)

Je vous ai montré, plus haut, l'importance de se déconnecter du portail captif avant de quitter le réseau mais je ne vous ai pas encore montré comment vous déconnecter de manière automatique. Nous allons faire en sorte de vous déconnecter automatiquement durant l'arrêt de votre machine.

La première étape est de trouver l'url et les paramètres de déconnexion. Tout comme pour la connexion automatique, il va falloir y aller au reverse. Tout comme pour la connexion automatique, vous devez obtenir une commande curl.

La deuxième étape est de modifier le fichier /etc/network/interfaces et d'y ajouter une ligne "pre-down". Cela demandera à la commande ifdown de vous déconnecter du portail avant de rendre l'adresse (si vous êtes en DHCP) et d'éteindre la carte réseau. Exemple :

allow-hotplug eth0
iface eth0 inet dhcp
pre-down curl -d pswd=votre_mdp -d uid=mon_login -d time=360 -d url= -d meth=radius -d action=logout "http://10.123.36.254/fin.html"

Attention : pour ceux qui seraient tenter d'utiliser wicd ou le network-manager, ce n'est pas une bonne idée. Ces deux services seront stoppés lors de l'arrêt et ne vous déconnecteront donc pas.

Pour ceux qui veulent se déconnecter sans pour autant éteindre leur machine, il n'y a pas, à ma connaissance, de méthode 100% automatique. Si vous avez modifié le fichier /etc/network/interfaces comme ci-dessus, vous pouvez lancer la commande "sudo ifdown eth0". Vous pouvez également placer votre commande dans wicd (Propriété de la connexion, Scripts, Exécuter un script avant déconnexion) ou le network-manager comme ça, vous aurez juste à cliquer sur "Déconnexion" pour quitter le portail captif et le réseau. Cette deuxième possibilité n'impose pas d'avoir modifié le fichier interfaces.

SSH auto-reconnect

Je vais finir ce billet en vous parlant d'un sujet qui n'a qu'un rapport limité avec le thème de ce billet : la reconnexion automatique à un serveur SSH. Vous savez que, sur les réseaux insécures, je fais transiter tout mon trafic par un tunnel SSH en attendant de me monter un VPN. Le keepalive permet de maintenir la connexion. Mais si jamais un problème survient sur le réseau et provoque une déconnexion, cela peut-être ennuyeux si je ne suis pas là pour relancer la connexion et si je télécharge un fichier, par exemple. C'est dans cette optique que j'ai créé le script suivant.

Il me semble au point, mais il y a sans doute moyen de l'améliorer. Il peut être simplifié, car il est, pour le moment, adapté à mes besoins/désirs :

  • Connexion au serveur SSH via le système clé publique/clé privée.
  • Je vérifie que la connexion est down via une requête DNS effectuée via mon tunnel SSH. Il est nécessaire d'ouvrir deux tunnels distincts (un pour le test, l'autre pour les données), car sinon, en cas de trafic dans le tunnel, la requête DNS de test n'est pas prioritaire et le script diagnostique, à tort, une connexion SSH down. Il est bien sûr possible de contrôler l'état de la connexion SSH via d'autres moyens comme la surveillance des connexions actives avec netstat ou la surveillance des processus actifs avec ps. Mais ces méthodes sont plus lentes pour détecter une connexion down du fait des timers, entre autres.
  • Ce script suppose que le serveur SSH soit configuré dans votre fichier ssh_config.
  • Ce script suppose que le port 53/tcp soit redirigé, grâce à iptables, sur le port 5300. je vous avais déjà expliqué pourquoi.
  • La commande dig doit être disponible sur le système (package dnsutils sous Debian).
  • Le résolveur DNS utilisé doit accepter les requêtes DNS sur le port 53/tcp.
  • Ce script est complexifié par le fait que le serveur SSH procède à un bannissement par IP après deux tentatives de connexion en moins de 10 minutes. C'est pourquoi le script attend 12 minutes en cas de reconnexion ratée et a été adapté à cette contrainte.

Trêve de parole, voici le script que j'utilise :

#!/bin/bash
 

ssh-add /chemin/vers/la/cle/privee
 
while true

do
	dig google.fr @127.0.0.1 +tcp > /dev/null 2>&1
	if [ $? -eq 0 ]; then

		echo "La connexion SSH est OK."
		sleep 60
	else
		echo "La connexion SSH semble KO."

		dig google.fr @127.0.0.1 +tcp > /dev/null 2>&1
		if [ $? -ne 0 ]; then

			echo "La connexion SSH est réellement KO."
			killall ssh > /dev/null 2>&1

 
			echo "Tentative de reconnexion ..."
			ssh -N -D6666 serveur &
			ssh -N -L5300:resolveurDNS:53 serveur &

 
			sleep 60   
			dig google.fr @127.0.0.1 +tcp > /dev/null 2>&1

			if [ $? -ne 0 ]; then
				echo "Tentative de reconnexion KO, attente de 12 minutes."

				killall ssh > /dev/null 2>&1
				sleep 720

			else
				echo "Tentative de reconnexion OK."
				sleep 60
			fi
		else

			echo "Mais la connexion est OK en fait."   
			sleep 60
		fi
	fi
done

13 commentaires pour le moment

Ajoutez votre commentaire
  1. tro classs votre tuto. jai ya mo

  2. salut super le billet! mais mon problème est un peu différent.je voudrai savoir s’il est possible de contourner un portail captif qui demande une authentification pour l’acces au réseau local!
    merci!

    • Heu ? Les portails captifs sont sur le réseau local justement donc les méthodes présentées dans le billet fonctionnent…

      • jai oublier de mentionner qu’il y a un serveur Radius derrriere!

        • Oups! bonjour d’abord ! 🙂

          • Ça ne nous avance pas beaucoup. :S Si c’est RADIUS derrière le portail captif, ça ne change pas la problématique : c’est toujours le portail captif qui appliquera la politique dont il aura eu connaissance via RADIUS, avec les mêmes travers que ça implique. Si c’est du 802.1X, ça change tout. 🙂

  3. salut au fait je suis sous windows 8.1 mais j ai du mal a faire la manip priere de bien vouloir m aider ou peut etre menvoyer les scripts en batch

  4. Superbe tuto.
    Merci et Bravo!

  5. bonjour,
    tout d’abord excusez moi car je n’ai aucune base d’informatique.
    Je suis en logement changeant tous les 6 mois; dans nos structures se trouvent des ports ethernet muraux; 1 par logement. La connexion internet se fait via un portail captif avec nos identifiants personnels attribués tous les 6 mois.
    La connexion filaire ne pose pas de problème j’ai donc pu, pour dépanner, partager ma connexion internet via wifi avec quelques simples lignes de codage et ce sans limite de temps.
    Malheureusement mon vieil ordinateur ne saurait rester allumé H24. Avant de commencer je précise que la connexion est limitée à un appareil(probablement 1 ip/adresse mac par personne)donc un routeur filaire n’y changerait rien. Il serait probablement possible de NATer d’autres appareils mais les autres appareils que j’utilise sont mon smartphone et ma tablette(qu’il me semble peu aisé de manipuler); à partir de là:
    Après avoir écumé les sites et avoir approximativement saisi 2 ou 3 notions j’ai donc décidé d’investir dans un routeur(qu’il me semble plus facile et plus durable dans le temps de NATer) afin de lui attribuer mon adresse ip et mac clonées préalablement authentifiée sur mon ordinateur; mais je me trouve en difficulté dans cette réalisation car je patauge. J’aimerai savoir si vous connaîtriez un tutoriel reprenant les bases des base afin de me permettre d’atteindre mon but.
    Merci bien
    cordiallement

    • Quelques éléments de réponse :
      * « afin de lui attribuer mon adresse ip et mac clonées préalablement authentifiée sur mon ordinateur; ». Je pense qu’il vaudrait mieux que ce soit le routeur qui se connecte au portail captif de manière automatique. Mais cela n’est pas possible de base avec le logiciel fourni par le constructeur du routeur. Il te faudra utiliser un firmware (le logiciel qui est embarqué dans le routeur) alternatif comme OpenWRT ou DD-WRT.

      * « mais je me trouve en difficulté dans cette réalisation car je patauge. ». Difficile de t’aider sans plus d’indications… Configure simplement le routeur via son interface web et attribue-lui l’IP qu’a obtenu ton ordinateur et basta.

      * Perso, plutôt qu’un routeur, je m’équiperais d’un ordinateur monocarte comme les OLinuXino + une antenne WiFi : ça consomme rien (pas plus qu’un routeur domestique en tout cas) et ça fera le job.

      • Merci bien je vais essayer le coup de la configuration web du routeur avec l’ip de l’ordi.
        Rien que ca se rapproche de mes limites alors le OLinuXino…
        Si je me retrouve dans l’impasse je passerai la main.
        En tout cas merci de la réponse rapide et des pistes potentielles, je m’aperçois qu’on ne s’improvise pas informaticien…
        Bonne journée!(et continuez comme ça les sujets sont mieux traités ou plus accessibles que ce que j’ai pu lire ailleurs)

  6. Merci bien pour la réponse ultra rapide je regarderais toutes ces infos ce we.
    N’y connaissant quasi rien(réellement) le OLinuXino me parait en dehors de mes possibilités…
    Je vais essayer essayer de configurer le routeur avec l’IP de mon ordi mais rien que ça n’est pas chose aisée; en cas d’échec je passerai la main en tout cas merci pour les infos et pour ces pistes!
    Bonne journée

  7. Est-il possible de rendre la commande de déconnexion automatique utilisable sur un plus grand réseau avec plusieurs personnes ayant accès à plusieurs postes ?