Pi Zero et USB-net (2)

Publié par cpb
Fév 12 2017

Pi Zero et USB-net

Dans l’article précédent, nous avons réussi à nous connecter depuis un PC hôte vers un Raspberry Pi Zero uniquement en employant un câble USB semblable à ceux pour téléphone portable.

Néanmoins, nous avions relevé plusieurs points restant à améliorer :

  • la connexion SSH est un peu longue à établir,
  • le Raspberry Pi Zero n’a pas accès à Internet,
  • il est nécessaire de fixer manuellement l’adresse IP de l’interface USB-net du côté PC.

Réglons ces problèmes un à un.

Accélérer la connexion SSH

Le serveur SSH (démon sshd) présent sur la distribution Raspbian du Pi Zero essaye d’identifier la machine qui vient se connecter en utilisant une résolution DNS. Puisque l’accès au DNS est impossible (pas d’accès Internet), et que même s’il était joignable il y a peu de chances qu’il connaisse le PC hôte, il faut attendre que le démon sshd échoue dans cette identification avant de poursuivre la connexion.

Nous pouvons désactiver aisément ce comportement en éditant le fichier de configuration de sshd (sur le Raspberry Pi Zero).

pi@raspberry:~ $ sudo vi /etc/ssh/sshd_config

Il suffit d’ajouter la ligne suivante à la fin du fichier :

/etc/ssh/sshd_config:
[...]
UsePAM yes

UseDNS no
pi@raspberry:~ $ sudo reboot

À partir de ce moment, la connexion sera plus aisée…

L’avantage de cette première solution est qu’elle est assez générique, je l’adopte sur la plupart des systèmes embarqués que je configure.

Dans notre cas spécifique, où une seule machine est susceptible de venir se connecter sur le serveur SSH, on peut adopter la solution proposée par Stéphane Peters en commentaire de l’article précédent. Il s’agit d’éditer le fichier /media/$USER/etc/hosts pour y ajouter une ligne identifiant le PC :

/media/$USER/etc/hosts:
[...]
192.168.7.1 host-pc

Accéder à Internet depuis le Raspberry Pi Zero

Lorsque nous somme sur le Pi Zero, la seule connexion vers l’extérieur est le lien USB-net point-à-point avec le PC hôte. Pour accéder à Internet il nous faudra donc passer par ce PC (à supposer bien sûr qu’il soit lui même relié au Net). Pour cela nous allons configurer les règles de routage et de filtration du noyau Linux du PC

Une fois la connexion établie, il suffit d’exécuter sur le PC quelques lignes de commande iptables pour activer le NAT (Network Address Translation) ainsi que la redirection (forwarding) au niveau IP.

Je pense que seules les deux dernières commandes sont indispensables, mais j’ai l’habitude d’exécuter le script ci-dessous complet afin de repartir d’une configuration vierge.

set-nat-rules.sh:
#! /bin/sh

# Inside network (without Internet access).
INSIDE=usb0

# Outside network (with Internet access).
OUTSIDE=eth0

# Flush the rules of the NAT table.
iptables -t nat -F  || { echo "$0: error while flushing NAT table rules." >&2; exit 1; }

# Delete the user-defined chains of the NAT table.
iptables -t nat -X  || { echo "$0: error while deleting NAT table chains." >&2; exit 1; }

# Reset the statistics of the NAT table.
iptables -t nat -Z  || { echo "$0: error while resetting NAT table counters." >&2; exit 1;
 }

# Flush the current forwarding rules.
iptables -F FORWARD || { echo "$0: error while flushing forwarding rules." >&2; exit 1; }

# Accept packets from INSIDE network to OUTSIDE network.
iptables -A FORWARD -i ${INSIDE} -o ${OUTSIDE} -j ACCEPT   || { echo "$0: error while conf
iguring ${INSIDE}->${OUTSIDE} forwarding." >&2; exit 1; }

# Apply NAT to OUTSIDE packets.
iptables -t nat -A POSTROUTING -o ${OUTSIDE} -j MASQUERADE || { echo "$0: error while conf
iguring NAT on ${OUTSIDE}." >&2; exit 1; }

# Activate the packet forwarding.
echo 1 > /proc/sys/net/ipv4/ip_forward || { echo "$0: error while enabling IP forwarding."
 >&2; exit 1; }

echo "Configuration OK." >&2

exit 0

J’exécute donc la commande suivante sur mon PC, après avoir ajusté les deux premières variables du script.

$ sudo ./set-nat-rules.sh

Et sur le Pi Zero je tente un accès vers Internet

pi@raspberrypi:~ $ ping www.kernel.org
PING pub.all.kernel.org (198.145.20.140) 56(84) bytes of data.
64 bytes from tiz-korg-pub.kernel.org (198.145.20.140): icmp_seq=1 ttl=46 time=166 ms
64 bytes from tiz-korg-pub.kernel.org (198.145.20.140): icmp_seq=2 ttl=46 time=188 ms
64 bytes from tiz-korg-pub.kernel.org (198.145.20.140): icmp_seq=3 ttl=46 time=174 ms
64 bytes from tiz-korg-pub.kernel.org (198.145.20.140): icmp_seq=4 ttl=46 time=167 ms
^C
--- pub.all.kernel.org ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 166.502/174.144/188.734/8.915 ms
pi@raspberrypi:~ $

Le temps de ping est un peu long (170 ms environ), à cause du réseau USB-net et de la redirection sur le PC, mais cela fera l’affaire pour notre usage.

On pourra noter qu’au bout de quelques dizaines de secondes, l’heure du Raspberry Pi Zero sera correctement mise à jour. Il inclut en effet un client NTP (Network Time Protocol) qui interroge régulièrement des serveurs distants.

Automatiser l’affectation d’adresse

Pour que le PC reçoive automatiquement une adresse IP lors de l’établissement de l’interface USB-net, il suffit d’installer un serveur DHCP sur le Raspberry Pi Zero.

Ceci est facile à faire, puisque nous disposons de tout le confort de la distribution Raspbian et de ses packages. Nous pouvons par exemple installer le petit serveur udhcpd (provenant de Busybox) facile à configurer.

pi@raspberrypi:~ $ sudo apt-get update
[...]
pi@raspberrypi:~ $ sudo apt-get install -y udhcpd
[...]

Il faut configurer le serveur DHCP pour lui indiquer les adresses qui nous intéressent.

pi@raspberrypi:~ $ sudo mv /etc/udhcpd.conf /etc/udhcpd.conf.backup
pi@raspberrypi:~ $ sudo nano /etc/udhcpd.conf

On peut utiliser une configuration très simple qui impose à notre correspondant (le PC) l’adresse 192.168.7.1 :

/etc/udhcpd.conf:
 start      192.168.7.1
 end        192.168.7.1
 interface  usb0
 max_leases 1
 option subnet 255.255.255.252

Nous devons également faire démarrer le serveur udhcpd automatiquement au boot. Pour cela nous devons modifier une option du fichier /etc/default/udhcpd.

/etc/default/udhcpd:
DHCPD_ENABLED="yes"
[...]
pi@raspberrypi:~ $ sudo reboot

Il devient possible, sur le PC, de modifier la configuration du Network Manager pour que l’interface USB-net soit initialisée automatiquement avec le protocole DHCP.

Boîte "Configuration de connexion filaire 1"

Attention à bien laisser cochée la case “Utiliser cette connexion uniquement pour les ressources de son réseau”. C’est ce qui nous garantit que nous pourrons continuer à accéder à Internet grâce à l’autre interface du PC.

Boîte "Modification des routes IPv4 pour Connexion filaire 1"

Conclusion

Nous avons obtenu une configuration assez confortable pour le Raspberry Pi Zero : simplement branché à un PC par un câble USB standard, il devient joignable via SSH sur une adresse IP connue, et peut accéder librement à Internet (pour peu que le PC fasse le relais).

URL de trackback pour cette page