Comment PXE démarrer sur WAN

J'ai actuellement un ordinateur Debian et un Raspbian Raspberry Pi sur mon réseau domestique derrière mon routeur. Le routeur a un port ouvert pour moi dans lequel je peux ssh dans le rPi quand je suis absent, puis une fois que je suis dans le réseau, je peux faire tout ce que je veux sur le réseau domestique.

Pendant le voyage, le disque dur de mon Debian PC semble être mort; À tout le moins, il refuse de démarrer.

Je n'ai laissé aucun CD de démarrage pour quiconque insérer car j'ai toujours démarré la boîte sur PXE, mon routeur domestique Tomato configuré pour pointer vers une machine virtuelle sur mon ordinateur portable pour servir les images BOOTP et TFTP nécessaires pour démarrer un installateur Linux, System Rescue CD ou Trinity Rescue Kit.

Ce portable est maintenant avec moi en voyage.

Puis-je configurer le renvoi de port SSH à partir de mon ordinateur portable lorsque je me connecte au rPi de ma maison et reconfigurer temporairement l'adresse IP à [je pense] dhcp-boot sorte que mon ordinateur Debian PXE puisse démarrer à l'aide de ma machine virtuelle Remote Laptop via Internet?

MISE À JOUR 3 août: suite à la suggestion de Matt ci-dessous, il y a eu un bon début mais toujours pas complet. Je ne suis toujours plus loin qu'avant.

Le serveur TFTP écoute le port UDP 69, mais il apparaît en utilisant l'option -R à ssh .

Ceci et ceci ont fourni une façon de procéder, en installant des tuyaux autour du tunnel pour traduire le trafic UDP vers TCP avant que le tunnel et TCP ne retournent à UDP après le tunnel, mais les commentaires indiquent que ce n'est pas la meilleure façon. En outre, cela n'a pas fonctionné pour moi.

L'utilisation de socat au lieu des tuyaux semblait produire moins de controverse, alors j'ai pensé que je l'essayerais, mais cela ne fonctionnait pas non plus.

Pour capturer ce que j'ai fait jusqu'ici, j'ai essayé de reproduire le problème localement sur mon ordinateur portable comme suit.

J'ai déjà ma VM exécutant le serveur TFTP sur le port 69 qui peut au moins servir un fichier pxelinux.0 .

J'ai créé une nouvelle VM qui démarre une image ISO de CD System Rescue. Lorsque j'ai démarré cette machine virtuelle, je l'ai configuré comme un serveur DHCP:

 # vi /etc/dhcp/dhcpd.conf 

Dans le fichier, j'ai spécifié ce qui suit:

 subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.251 192.168.1.253; option routers 192.168.1.1; filename "pxelinux.0"; next-server 192.168.1.252; } 

Ensuite, j'ai redémarré le serveur DHCP:

 # /etc/init.d/dhcpd restart 

Remarque: J'ai maintenant deux serveurs DHCP sur ce réseau «étranger» – le routeur qui a fourni à mon ordinateur portable son adresse IP, et maintenant cette machine virtuelle jusqu'à ce qu'elle soit coupée. Cela introduit une condition de course car ma VM de démarrage PXE peut recevoir une réponse du serveur DHCP; J'espère que la réponse de ma VM est la première à atteindre la VM PXE afin qu'elle puisse obtenir la directive next-server ci next-server dessus.

Dans la pratique avec mes exercices limités, il semble que ce ne soit pas un problème, mais je ne veux pas laisser ma VM pendant trop longtemps, donc je ne dérange personne d'autre ici.

Comme indiqué, avec le serveur DHCP en cours d'exécution, j'ai démarré ma troisième machine virtuelle sans disque pour le démarrage PXE pour exercer le processus de démarrage PXE.

L'hôte .252 était mon serveur PXE, de sorte que la machine virtuelle PXE-boot était capable de l'atteindre, d'obtenir les fichiers nécessaires via TFTP et a commencé à démarrer comme d'habitude.

Avec le fonctionnement du cas nominal, j'ai décidé d'introduire le tunnel SSH dans le mélange, comme l'a suggéré Matt.

 # vi /etc/dhcp/dhcpd.conf 

J'ai modifié next-server à l'adresse IP de la machine à convection CD System Rescue:

 subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.251 192.168.1.253; option routers 192.168.1.1; filename "pxelinux.0"; next-server 192.168.1.13; } 

Ensuite, j'ai redémarré le serveur DHCP:

 # /etc/init.d/dhcpd restart 

J'ai également vérifié qu'aucun serveur TFTP ne fonctionnait sur cette boîte:

 # netstat -an | grep 69 

Maintenant, ma machine virtuelle de démarrage PXE a échoué à démarrer. Il a reçu une adresse IP du serveur DHCP mais n'a pas pu récupérer une image de démarrage TFTP.

J'ai apporté la clé publique du serveur PXE et l'ai placé dans le fichier root authorized_keys .

Du serveur PXE VM, j'ai créé mon tunnel:

 $ ssh -R 69:localhost:69 -R 2049:localhost:2049 root@192.168.1.13 

Notez que je n'avais pas besoin de transférer le port 2049 à ce moment-là, mais je devrais le faire plus tard pour NFS.

Le même problème lors du démarrage de PXE VM: Impossible d'obtenir l'image sur TFTP.

Le serveur TFTP écoutait le port UDP 69:

 udp 0 0 0.0.0.0:69 0.0.0.0:* 

Cependant, le port renvoyé écoute sur TCP:

 tcp 0 0 127.0.0.1:69 0.0.0.0:* LISTEN tcp6 0 0 ::1:69 :::* LISTEN 

Essayé l'approche initiale de l'utilisation des tuyaux. Sur la machine à sous de CD System Rescue:

 # mkfifo /tmp/fifo # nc -v -l -u -p 6963 < /tmp/fifo | nc -v -u 127.0.0.1 6964 > /tmp/fifo 

Pendant ce temps, sur le serveur PXE VM:

 $ ssh -R 6964:localhost:6965 root@192.168.1.13 $ nc -v -l -p 6965 < /tmp/fifo | nc -v -u localhost 69 > /tmp/fifo 

À partir de la machine à sous du système de sauvegarde de CD, j'ai essayé de transférer manuellement le fichier:

 # tftp localhost 6963 -c get pxelinux.0 connect to [127.0.0.1] from sysresccd.gentoo [127.0.0.1] 51072 too many output retries : Broken pipe 

Cela ne fonctionnait toujours pas, alors j'ai essayé de nouveau de prendre le tunnel hors de l'équation.

System Rescue CD VM:

 # nc -v -l -u -p 6963 < /tmp/fifo | nc -v -u 127.0.0.1 6965 > /tmp/fifo 

PXE server VM:

 $ nc -v -l -p 6965 < /tmp/fifo | nc -v -u localhost 69 > /tmp/fifo 

Transfert sur système de sauvegarde de système VM:

 # tftp localhost 6963 -c get pxelinux.0 

Cela ne fonctionnait toujours pas, alors j'ai nettoyé avec rm /tmp/fifo sur les deux boîtes.

Ensuite, j'ai procédé à la tentative de socat , mais cela avait des résultats similaires. J'ai également pris le tunnel SSH hors de l'équation là-bas, avec les mêmes résultats.

Cette fois, je ne pouvais pas utiliser la machine à sous du système de sauvetage car elle ne venait pas avec socat installée, alors j'ai utilisé une machine virtuelle différente.

Tout d'abord, je voulais vérifier que le serveur TFTP actuel était toujours disponible:

 $ tftp 192.168.1.252 tftp> get pxelinux.0 tftp> quit 

Bien sûr, j'ai eu un fichier de zéro-octet téléchargé.

Cela n'a pas fonctionné lorsque j'ai utilisé une boîte sans rien écouter sur le port TFTP:

 $ tftp localhost tftp> get pxelinux.0 Transfer timed out. tftp> quit boots$ rm pxelinux.0 

Le temps de mettre le socat dans le mélange.

Sur le serveur PXE:

 $ ssh -p 22 -R 6969:localhost:6968 192.168.1.7 $ sudo socat UDP4-LISTEN:69,fork TCP4:localhost:6969 

Dans une autre fenêtre sur le serveur PXE:

 $ socat -T10 TCP4-LISTEN:6968,fork UDP4:localhost:69 

Cela ne marchait toujours pas:

 $ tftp localhost tftp> get pxelinux.0 Transfer timed out. tftp> quit boots$ rm pxelinux.0 

Mise à jour 4 août: Je pense que j'ai trouvé mon problème, mais je ne sais pas trop comment le passer.

J'ai rendu ma configuration encore plus basique. J'ai éliminé complètement le tunnel SSH et collé aux ports UDP directs.

Sur mon client local TFTP, ceci:

 $ sudo socat -d -d -d -d udp4-recvfrom:69,reuseaddr,fork udp:192.168.1.252:69 

Rappel que la boîte .252 est le serveur TFTP.

Cela ne marchait toujours pas:

 $ tftp localhost tftp> get pxelinux.0 Transfer timed out. tftp> quit boots$ rm pxelinux.0 

Donc, j'ai couru Wireshark sur les deux .7 et les .252 en regardant le trafic UDP et en particulier le trafic TFTP.

Voici mes filtres de capture sur les deux instances de Wireshark:

  • .7: udp et hôte 192.168.1.252 et port non 123
  • .252: udp et hôte 192.168.1.7 et port non 123

Lorsque j'ai couru cela, j'ai vu beaucoup de trafic TFTP sur un port autre que 69. Dans ce cas, les paquets de données sont passés du port 60862 sur l'hôte source à 44792 sur la destination, et les accusés de réception sont retournés dans les autres ports.

Selon Wikipedia :

Une demande de transfert est toujours lancée en ciblant le port 69, mais les ports de transfert de données sont choisis indépendamment par l'expéditeur et le récepteur pendant l'initialisation du transfert. Les ports sont choisis au hasard selon les paramètres de la pile de réseau, généralement à partir de la gamme des ports éphémères.

Si je comprends bien cela, je devrai faire un tunnel plus que le port 69. Quelles sont les commandes supplémentaires dont j'ai besoin pour que ces ports soient transmis? Y a-t-il un moyen simple de le faire?

Mise à jour 5 août: Je pourrais avoir un autre problème avant cela.

En ce qui concerne l'article ci-dessus, j'ai essayé de jouer avec TFTP un peu plus et de regarder les paquets dans Wireshark. Il semble que je reçois le premier paquet sur le port 69 à partir d'un port source aléatoire. Dans le dernier cas, c'était le port 48723.

Il s'avère que le serveur TFTP envoie des paquets UDP sur ce port à partir d'un autre port. Si je peux surveiller le premier paquet vers le port 69, je peux le voir et je m'attends à ce que je puisse rapidement configurer un autre tunnel de manière similaire sur ce port avant qu'il ne soit éteint, donc le processus sera un peu manuelle, mais je pourrais être Capable de l'éliminer.

Maintenant que je regarde de près, il semble que je ne reçois pas le premier paquet sur le socat .

Quand je n'ai pas de tunnel, je vois le paquet initial sur le port 69 sans problème.

Lorsque j'ai mis en place un socat direct sans tunnel SSH comme suit, je ne vois aucun paquet.

Fenêtre 1:

 $ sudo socat -d -d -d -d udp4-recvfrom:69,reuseaddr,fork udp:192.168.1.252:69 

Fenêtre 2:

 $ tftp localhost tftp> get pxelinux.0 Transfer timed out. 

Voici le résultat de netcat :

 $ netstat -an | grep 69 | grep udp udp 0 0 0.0.0.0:69 0.0.0.0:* 

J'ai également une instance Wireshark fonctionnant des deux côtés; Les deux ne montrent absolument rien. Voici mon filtre de capture des deux côtés:

 udp and not (port 123 or port 5353 or port 1900) 

J'ai ouvert une autre question à ce sujet.

Mise à jour: un petit pas en avant. Je soupçonne que j'ai quelque chose de mal avec ma commande socat maintenant.

J'ai essayé un autre test simple sur mon ordinateur portable uniquement.

Fenêtre 1:

 $ sudo nc -v -l -u 69 

Wireshark:

  • Écoutez sur l'interface
  • Filtre de capture: udp et port 69

Fenêtre 2:

 $ nc -u 127.0.0.1 69 

Lorsque j'ai tapé dans la Fenêtre 2, j'ai vu la sortie dans la Fenêtre 1 et j'ai vu des paquets capturés dans Wireshark.

Ensuite, j'ai répété avec la carte réseau de mon ordinateur portable:

Fenêtre 1:

 $ sudo nc -v -l -u 69 

Wireshark:

  • Écoutez sur l'interface wlan0
  • Filtre de capture: udp et port 69

Fenêtre 2:

 $ nc -u 127.0.0.1 69 

Il s'avère que je ne recevais aucun paquet capturé à Wireshark, même si j'avais des messages dans la Fenêtre 1. Je me suis souvenu de mettre en place Docker il y a quelque temps, donc j'avais un pont docker0; J'ai également quelques produits de virtualisation, donc peut-être qu'ils ont été gênés.

J'ai ré-exécuté la capture de Wireshark avec:

  • Écoutez sur l'interface
  • Filtre de capture: udp et port 69

Cette fois, j'avais tout ce que je voulais. Peut-être que mon problème était l'interface de capture de Wireshark tout au long.

Arrêté les fenêtres netcat, et reculez un peu en arrière maintenant:

 $ sudo socat -d -d -d -d udp4-recvfrom:69,reuseaddr,fork udp:192.168.1.252:69 

Essayé à nouveau le test TFTP:

 $ tftp localhost tftp> get pxelinux.0 

C'était ça! Je reçois mes paquets capturés à Wireshark maintenant!

Je vois que les messages de demande de lecture sont capturés, et il s'avère que les cinq tentatives / tentatives proviennent du même port source.

Maintenant, le temps de voir si je peux configurer manuellement une session socat supplémentaire sur ce port source. Sur le serveur TFTP lui-même, j'ai en outre couru:

 $ for f in 52163; do socat -d -d -d -d udp4-recvfrom:${p},reuseaddr,fork udp:192.168.1.7:${p}; done 

Notez que cela avait l'adresse IP de mon ordinateur portable. (La boucle for est simplement pour la commodité, donc je n'ai besoin que de spécifier le numéro de port une fois dans la commande.)

Il s'avère que chacun des ports source est le même, peu importe le nombre de fois que je lance la commande PXE get pxelinux.0 ; Le numéro du port source change lorsque je quitte TFTP et que j'exécute TFTP.

J'ai installé Wireshark sur mon ordinateur portable et sur la boîte TFTP; Je vois maintenant des paquets sur le Wireshark de mon ordinateur portable mais pas sur le Wireshark de TFTP.

Je suppose qu'il y a quelque chose qui ne va pas avec ma commande socat , mais je ne sais pas ce que c'est:

 $ sudo socat -d -d -d -d udp4-recvfrom:69,reuseaddr,fork udp:192.168.1.252:69 

Mise à jour: alors, maintenant que j'ai les bases basiques pour netcat, j'ai pensé prendre un pas en avant en introduisant socat dans le mix mais toujours pas de tunnel ssh.

J'ai mon ordinateur portable local et, pour l'instant, appelons le serveur TFTP dans la zone de la télécommande même s'il s'agit d'une machine virtuelle sur mon ordinateur portable.

Fenêtre 1:

 local$ sudo socat udp4-recvfrom:69,reuseaddr,fork udp:192.168.1.13:69 

Fenêtre 2:

 local$ nc -4u localhost 69 

Wireshark s'exécutant sur une caméra distante capturant le trafic UDP.

Dans la fenêtre 2, j'ai tapé trois lignes, en appuyant sur Entrée après chacune: "un", "deux" et "trois".

Dans Wireshark, je vois trois paquets sur le port TFTP, de sorte que le serveur TFTP doit obtenir ces données sur les ordures. Ce qui est intéressant ici est que chacun des trois paquets a un autre port source.

Ensuite, j'ai quitté netcat et j'ai utilisé plutôt le client TFTP spécifiant l'adresse IP locale au lieu de "localhost" depuis que je l'ai brûlé aujourd'hui:

 local$ tftp 127.0.0.1 tftp> get pxelinux.0 

Maintenant, je reçois le paquet TFTP Read Request de mon ordinateur portable local!

(FYI avant de capturer mes notes ici, j'ai couru "tftp localhost" et encore une fois rien trouvé. On dirait le problème IPv4 / IPv6 mentionné dans mon autre question .)

Donc revenons maintenant au tunnel SSH.

Fenêtre 1:

 remote$ socat tcp4-listen:6901,reuseaddr,fork udp:127.0.0.1:69 

Fenêtre 2:

 local$ ssh -L 6901:127.0.0.1:6901 192.168.1.13 

Fenêtre 3:

 local$ sudo socat udp4-recvfrom:69,reuseaddr,fork tcp:127.0.0.1:6901 

Je reçois les paquets de demande de lecture capturés dans Wireshark avec le premier paquet de données qui ne peut pas aller n'importe où car il n'y a pas de tunnel sur le port source, mais au moins je reçois les paquets UDP sur le tunnel au serveur TFTP !

Maintenant, cela m'a fait réfléchir un peu plus sur ce voyage de retour. Avec socat au milieu, il me semble que je reçois cinq tentatives de transfert de ce client TFTP avant qu'il socat ; Je ne sais pas comment le client TFTP dans le microprogramme NIC se comportera.

Pour chacune de ces tentatives, il semble que je reçois un autre port source depuis que la connexion au serveur TFTP provient de socat et non du client TFTP de mon ordinateur portable. Encore une fois, je ne sais pas comment le client TFTP intégré au microprogramme NIC se comportera.

Même si je surveille le trafic et crée un tunnel de retour assez rapidement après avoir vu le trafic à Wireshark, je ne sais pas si c'est trop tard.

Je suppose que la même chose sera vraie si j'avais utilisé des tuyaux au lieu de socat .

Mise à jour: je pense que je suis prêt à renoncer à cela, mais juste pour le plaisir, j'ai pensé que je retournerais à la boîte d'origine et essayer de capturer des paquets maintenant que j'ai assez pour obtenir au moins un voyage.

Ma notion de «local» et de «distance» est maintenant inversée car mon serveur TFTP est local alors que mon ordinateur mort est distant.

Fenêtre 1:

 laptop$ ssh user@192.168.1.13 local$ socat tcp4-listen:6901,reuseaddr,fork udp:127.0.0.1:69 

Fenêtre 2:

 laptop$ ssh -R 6901:127.0.0.1:6901 user@remote.fqdn.net remote$ ping -i 60 8.8.8.8 

(Le ping est de conserver la connexion en cas de besoin.)

Fenêtre 3:

 laptop$ ssh user@remote.fqdn.net remote$ sudo socat udp4-recvfrom:69,reuseaddr,fork tcp:127.0.0.1:6901 

Je me suis inquiété du changement du port source avec socat , alors j'ai été curieux d'essayer de nouveau les tuyaux. Je suis retourné à ma configuration de test.

Je garde mon système local et distant inversé pour assurer la cohérence avec l'environnement de production même s'il est à l'envers pour mon environnement de test.

Fenêtre 1:

 laptop$ ssh 192.168.1.13 local$ mkfifo /tmp/fifo local$ nc -lp 6901 < /tmp/fifo | nc -u 127.0.0.1 69 > /tmp/fifo 

Fenêtre 2:

 laptop$ ssh 192.168.1.13 local$ ssh -R 6902:127.0.0.1:6901 192.168.1.7 remote$ ping -i 60 8.8.8.8 

Fenêtre 3:

 remote$ mkfifo /tmp/fifo remote$ sudo nc -lup 69 < /tmp/fifo | nc 127.0.0.1 6902 > /tmp/fifo 

J'ai essayé un TFTP simple à partir de mon compte TFTP à nouveau. Cette fois, j'ai remarqué dans Wireshark que le port source était le même pour chaque paquet! Peut-être qu'il y a encore de l'espoir !!

Rappelez-vous la mise en garde pour cela, c'est que les paquets UDP restent sous la taille du MTU, ce qui, je crois, j'ai lu quelque part qu'ils seront pour TFTP.

Je dois nettoyer mes pipes:

 local$ rm /tmp/fifo remote$ rm /tmp/fifo 

Je voulais essayer cela sur la production maintenant.

Fenêtre 1:

 laptop$ ssh user@192.168.1.13 local$ mkfifo /tmp/fifo local$ nc -lp 6901 < /tmp/fifo | nc -u 127.0.0.1 69 > /tmp/fifo 

Fenêtre 2:

 laptop$ ssh user@192.168.1.13 local$ ssh -R 6901:127.0.0.1:6901 user@remote.fqdn.net remote$ ping -i 60 8.8.8.8 

(Le ping est de conserver la connexion en cas de besoin.)

Fenêtre 3:

 laptop$ ssh user@remote.fqdn.net remote$ mkfifo /tmp/fifo remote$ sudo -i remote$ nc -lup 69 < /tmp/fifo | nc 127.0.0.1 6901 > /tmp/fifo 

Lorsque j'ai eu le PC démarré, j'ai eu un paquet TFTP jusqu'au serveur PXE selon Wireshark, mais je n'ai pas eu les tentatives. J'espérais obtenir les tentatives aussi, et que tous auront le même port source.

J'ai changé les nc sur le côté gauche des tuyaux pour spécifier aussi -k pour conserver en vie, puis redémarré, mais je n'ai encore reçu que le premier paquet.

Je dois nettoyer mes pipes:

 local$ rm /tmp/fifo remote$ sudo rm /tmp/fifo 

One Solution collect form web for “Comment PXE démarrer sur WAN”

Cela devrait fonctionner, à partir des documents ssh :

-R remote_socket: local_socket
Spécifie que les connexions au port TCP donné ou au socket Unix sur l'hôte distant (serveur) doivent être transmises à l'hôte et au port donnés

Étant donné que le port 69 est un port privilégié, vous devez également savoir que:

Les ports privilégiés peuvent être transférés uniquement lorsque vous vous connectez en tant que root sur la machine distante.


Modifiez d'abord dnsmasq.conf et modifiez votre option dhcp-boot; Le port de destination sera le pi de framboises.

De votre ordinateur portable local,

 $ ssh root@port.forwarded.pi -R 69:69 

Une fois que ce port en attente est établi, essayez de redémarrer la machine Debian.

Sur le démarrage PXE, la machine doit faire appel à l'option de démarrage DHCP au pi.

La demande TFTP sur le port 69 entrera dans le port ouvert par le tunnel SSH, en envoyant ce paquet sur 127.0.0.1:69 sur votre ordinateur portable local.

En supposant que vous exécutez le serveur TFTP sur le port 69, l'image doit être téléchargée.

Soyons le génie de l'ordinateur et du réseau.