Voici un article un peu particulier car son but premier est de partager comme d’habitude avec la communauté mais il a aussi pour moi une saveur d’aide mémoire, car le but est que je perde moins de temps la prochaine fois que j’aurais besoin de cette astuce.
Les symptômes
Ces derniers temps j’ai pas mal (pour pas dire beaucoup) travaillé sur mes machines virtuelles j’en ai créées, supprimées, dupliquées à partir de snapshot, … Et il arrive toujours un moment où on se mélange un peu les pinceaux entre les 5 vms Ubuntu et les 3 debian sans parler de la lubuntu et on se dit mais ça je suis sûr ça a marché il y a quelques semaines mais sur quelle vm et comment ? Le ça représente quelque chose d’assez simple, le but est d’accéder à une application django tournant en serveur de développement sur un système invité depuis le navigateur du système hôte. Trop facile vous dîtes, attendez la suite.
Par défaut sur un projet django, lorsque l’on lance la commande ./manage.py runserver
, le serveur de développement se lance sur http://127.0.0.1:8000, ok classique pour un serveur de développement local, pas surpris. Ayant aisément fait une redirection de port dans virtualbox pour rediriger le port 2222 de la machine hôte vers le port 22 de la machine invitée, je pars la fleur au fusil faire une redirection tcp du port 8080 de la machine hôte vers le port 8000 de la machine invité, je prends mon plus beau navigateur et je tape dans ce dernier http://127.0.0.1:8080 et là ça ne marche pas (sinon j’écrirais pas cet article 😉 ).
La première solution mais pas la bonne à mon goût
Après avoir cherché vraiment longtemps, je me dis ce n’est pas grave on a une connexion ssh on peut donc tout faire passer par là avec un joli tunnel ssh (redirection de port à travers ssh et non plus virtualbox) comme ceci : ssh -L 8080:localhost:8000 user@localhost -p 2222
, un peu d’explication -L pour redirection locale de port, 8080 le port de la machine hôte que j’ai choisi pour accéder à la machine distante (ici une machine invitée dans virtualbox). Localhost:8000, représente ici le localhost et le port de la machine sur laquelle la connexion ssh va s’opérer, ici cela représente donc bien le 127.0.0.1:8000 de base du serveur django. Enfin user@localhost -p 2222 représente la façon dont je me connecte sur la machine distante (ici la machine invitée sous virtualbox) car quand je veux me connecter en ssh sur la machine invitée je lance la commande suivante ssh -p 2222 user@localhost (fonctionnant par une redirection de port virtualbox). Ensuite je prends mon plus beau navigateur et je tape dans ce dernier http://127.0.0.1:8080 et là ça marche super on a dû « hacker » notre propre système sous notre maîtrise toute relative pour pouvoir accéder à une interface web. Enfin au passage ça rappelle de bon moyens de se faire un VPN pas chère ou toutes choses du genre…
La seconde solution, c’est la bonne
Bon le souci de la première solution c’est quelle laisse le doute sur le fait que la redirection de ports en virtualbox ne fonctionnerait que pour le port 22 forcément ce n’est pas possible, j’ai fait de nombreuses recherches sur internet qui m’indiquait le contraire. Ou alors serait-ce mon système hôte Ubuntu dans mon cas, pareil après quelques recherches cette hypothèse et écartée. Le firewall d’ubuntu à coup d’iptables et de ufw je m’aperçoit que non. Cela reste très gênant et enfin je décide d’orienter mes recherches vers django et là je tombe sur ce forum https://ubuntuforums.org/showthread.php?t=2260190 et là je comprends mieux, la redirection de port en tcp du port hôte 8080 vers le port 8000 de la machine invitée fonctionnait parfaitement bien depuis le début mais simplement django n’acceptez que les connexions locales. La solution est trouvée il faut lancer la commande suivante afin que le serveur accepte les connexions non locales ./manage.py runserver 0.0.0.0:8000
(bien évidemment il faut penser à reconfigurer la redirection de ports si vous l’aviez enlevé) et voilà tout fonctionne parfaitement. Le 0.0.0.0 indique dans ce cas toutes les adresses ips de la machine sur toutes ses interfaces réseaux, ce qui est bien plus ouvert que 127.0.0.1 qui lui n’autorisera la connexion que sur la boucle locale (=> localhost), des infos en détails ici : https://www.it-swarm.dev/fr/networking/quelle-est-la-difference-entre-127.0.0.1-et-0.0.0.0/958652984/
Mais alors pourquoi le pont ssh fonctionnait
Et bien simplement parce que lorsque que l’on met en place le pont à travers SSH, la connexion entrante est considérée comme une connexion locale pour django il n’y a pas de traces de la machine hôte pour django seulement pour ssh, une traduction en quelques sortes (souvenez vous le localhost de la machine distante 😉 ), tout s’explique et c’est bien mieux ainsi. Conclusion pour développer en python – django depuis une vm virtualbox et avoir le navigateur sur la machine hôte, il faut prendre le réflexe de lancer le serveur avec l’ip 0.0.0.0 plutôt que de laisser celle par défaut. Bon on peut faire autrement mais je vous en parlerais dans un prochain article où je vous donnerais un petit bonus patience…