Publié par et
Il y a 1 année · 12 minutes · IoT

Atelier – Outillage 1 : accéder à son RaspberryPi en access point

L'atelier IoT

Nous aimons beaucoup le Raspberry Pi pour prototyper des objets (d’ailleurs nous espérons, comme beaucoup, pouvoir rapidement mettre la main sur quelques Pi Zero !). Mais, à chaque fois, instancier un projet sur Pi est un parcours du combattant.

Il y a la méthode à l’ancienne : dégotter un clavier, emprunter un écran, voler le câble HDMI de la XBox, et c’est parti.

Il y a la méthode hacker : brancher le pi sur un câble ethernet, balancer un nmap -sS -p 22 <ip>/24 | grep Rasp -B 4, aller prendre un café (ou quatre, en fonction de la taille et de la complexité du réseau), et travailler en SSH depuis son PC.

Et puis, il y a la méthode smart : transformer son Pi en Access Point, se connecter dessus en wifi avec SSH. C’est cette dernière méthode que nous allons décrire ici, en l’illustrant avec des trésors du patrimoine musical francophone.

 

 

 

Claude François : Comme d’habitude

Première étape, installer un OS pour votre Pi. Pour cela, c’est comme d’habitude, une Raspbian sur une carte SD. Pas de secret, le tutoriel est extrêmement bien fait, suivez le pas à pas.

Pour la suite des tutoriels, vous pouvez vous contenter de l’installation d’une Jessie Lite.

C’est à partir de ce moment que nous allons abandonner les méthodes à l’ancienne et hacker, en nous passant des accessoires superflus.

Rika Zarai : Sans chemise, sans pantalon

L’idée maitresse est de modifier le comportement du Pi au boot pour que l’insertion d’une clé USB Wifi dite Admin déclenche l’émission d’un Access Point wifi sur lequel vous pourrez vous connecter directement en SSH.

La création de l’Access Point est basée sur l’excellent article elinux dédié, dans lequel nous avons remplacé udhcp par dnsmasq pour des questions de goûts.

Manipuler Raspbian depuis sa machine

Pour cela, nous allons continuer de manipuler l’OS du RPi directement à partir de notre machine (Mac, GNU/Linux, Windows, choisissez vos armes !). Pour intervenir sur la partition système de la carte SD, il vous faut monter un filesystem EXT. Malheureusement, seul GNU/Linux offre cette option de manière native.

Pour OSX, il vous faudra passer par un logiciel tiers, Fuse Ext2.

Attention DISCLAIMER : Fuse Ext2 ne pose aucun soucis en read-only, mais il semblerait que dans certaines conditions, le mode write puisse griller votre carte SD. Depuis que nous utilisons cette méthode, nous n’avons jamais eu à faire face à cette mésaventure. Néanmoins, soyez conscient que vous pourriez perdre une carte SD dans la bataille.

Dans la suite de l’article, nous nous réfèrerons au point de montage de votre carte SD en utilisant la variable $RASPBIAN_SD.

Démarrer les installations

Une fois votre carte SD montée, nous allons lui ajouter un fichier exécutable au boot.

Créez et éditez le fichier $RASPBIAN_SD/etc/rc.local comme suit :

#!/bin/bash

VAR_FB=/var/lib/first-boot-setup
 
if [[ ! -d $VAR_FB ]] ; then
  mkdir $VAR_FB
fi
 
# checking if we already ran this script
if [[ -f $VAR_FB/initialized ]] ; then
  logger -t "first boot" "first boot setup already done, skipping"
  echo "first boot setup already done, skipping"
else
  echo "Starting init script"
  sudo apt-get update
  sudo apt-get install -y --force-yes -o Dpkg::Options::="--force-confold" -o Dpkg::Options::="--force-confold" hostapd dnsmasq
  sudo update-rc.d dnsmasq enable
  touch $VAR_FB/initialized
 
  sudo ifdown wlan0
  sudo ifup wlan0
  logger -t "first boot" "first boot setup done !"
  echo "first boot setup done !"
fi

exit 0

Hostapd va permettre à votre clé USB Wifi de fonctionner en mode émetteur si elle le supporte.

DnsMasq va permettre à votre Pi de fonctionner en mode serveur DHCP pour donner un adresse à votre poste de développement lorsque vous vous connecterez en SSH.

Seconde étape, nous allons paramétrer hostapd en créant le répertoire $RASPBIAN_SD/etc/hostapd et en éditant <point de montage SD>/etc/hostapd.conf

# Interface to bind to
interface=wlan0
# Driver, depending on your wifi hardware
driver=nl80211
# The SSID you want to broadcast
ssid=RPi-Atelier
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
# Security parameters
wpa=2
wpa_passphrase=password
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

Troisième étape, le paramétrage de DnsMasq, dans le fichier $RASPBIAN_SD/etc/dnsmasq.conf

# Disables dnsmasq reading any other files like /etc/resolv.conf for nameservers
no-resolv
# Interface to bind to
interface=wlan0
# Specify starting_range,end_range,lease_time
dhcp-range=192.168.0.2,192.168.0.20,12h
# dns addresses to send to the clients
server=8.8.8.8
server=8.8.4.4

Dernière étape, donner une IP fixe au RPi, en éditant le fichier $RASPBIAN_SD/etc/network/interfaces

# Local interface
auto lo
iface lo inet loopback
# Ethernet interface
iface eth0 inet manual
# Wifi interface (to be modified)
iface wlan0 inet static
hostapd /etc/hostapd.conf
 &nbsp;address 192.168.0.1
  netmask 255.255.255.0

Dernière manipulation, attribuer les bons owners et les bonnes permissions aux fichiers que vous avez modifiés.

$ chown -R root:wheel etc/hostapd.conf
$ chown -R root:wheel etc/dnsmasq.conf

Enfin est venu le temps de tester. Démontez proprement votre carte SD, glissez là dans votre Pi, et branchez un câble RJ45 à internet et l’alimentation. Au bout de quelques minutes, vous devriez voir apparaitre sur votre PC le SSID souhaité.

Herbert Léonard : Pour le plaisir

Là, on commence à être pas mal.

Mais quand même… Il reste ce câble RJ45 connecté au Pi et tous ces fichiers de configuration à taper dans de nombreux endroits. Pourrait-on, pour le plaisir, faire plus simple ? Vous vous en doutez : la réponse est oui.

Il existe un ensemble de protocoles Zeroconf dont le but est de permettre la configuration du réseau sans avoir besoin de services d’infrastructures. Bonjour d’Apple, APIPA chez Windows et Avahi sous Linux sont des implémentations de ces protocoles sous chacun des systèmes d’exploitation. Nous allons donc faire usage de ces protocoles pour implémenter notre accès WiFi au RPi !

Nous allons donc reprendre juste après avoir monté le fileSystem fraichement installé sur sa carte SD.

Configuration du réseau WiFi

Debian a intégré un mode ipv4ll au sein de son système de configuration réseau depuis Wheezy, lequel facilite la mise en place de protocoles Zeroconf. Ce mode suppose que la commande avahi-autoipd soit disponible sur le système, mais elle n’est pas installée par défaut. Nous allons donc devoir l’installer au premier boot avant de démarrer le réseau.

Pour cela, le hook pre-up semble tout indiqué, voici donc un script qui effectuera ces actions, à placer dans $RASPBIAN_SD/usr/local/sbin/first-boot-setup :

#!/bin/bash

VAR_FB=/var/lib/first-boot-setup

if [[ ! -d $VAR_FB ]] ; then
  mkdir $VAR_FB
fi

# checking if we already ran this script
if [[ -f $VAR_FB/initialized ]] ; then
  logger -t "first boot" "first boot setup already done, skipping"
  echo "first boot setup already done, skipping"
else
  dpkg -i /var/tmp/avahi-autoipd*.deb
  touch $VAR_FB/initialized

  logger -t "first boot" "first boot setup done !"
  echo "first boot setup done !"
fi

exit 0

Pour que ceci fonctionne, vous devez télécharger le package avahi-autoipd depuis les dépôts de Raspbian et le déposer dans $RASPBIAN_SD/var/tmp tel quel et donner les droits d’exécution à notre script :

wget http://mirrordirector-mb.raspbian.org/raspbian/pool/main/a/avahi/avahi-autoipd_0.6.31-5_armhf.deb -O $RASPBIAN_SD/var/tmp/avahi-autoipd_0.6.31-5_armhf.deb
chmod +x $RASPBIAN_SD/usr/local/sbin/first-boot-setup

Il reste maintenant à configurer le réseau. Éditez le fichier $RASPBIAN_SD/etc/network/interfaces et modifiez-le pour qu’il ait le contenu suivant :

# Local interface
auto lo
iface lo inet loopback
# Ethernet interface
iface eth0 inet manual

# Wifi interface (to be modified)
auto wlan0
iface wlan0 inet ipv4ll
pre-up /usr/local/sbin/first-boot-setup
    wireless-channel 6
    wireless-essid RPi-Atelier
    wireless-mode ad-hoc

Configuration d’Avahi pour exposer le serveur SSH

Créez maintenant le fichier $RASPBIAN_SD/etc/avahi/services/ssh.service avec le contenu suivant :

<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">%h SSH</name>
<service>
<type>_ssh._tcp</type>
<port>22</port>
</service>
</service-group>

Ce fichier déclare à Avahi la présence du service SSH sur le système, information qu’il publiera sur le réseau ensuite.

Vous pouvez maintenant remettre votre SD dans le Pi et le démarrer.

Bienvenue sur votre Pi, sans configuration DNS ni DHCP !

Bien que cette méthode fonctionne, elle n’est pas complètement satisfaisante. En effet, malgré tous nos efforts, nous n’avons pas réussi à forcer une authentification WPA sur notre connexion. Même si elle est bien plus élégante que la version hostapd / dnsmasq, il n’est pas envisageable de faire un réseau d’administration ouvert. Nous nous sommes donc rabattus sur une installation offline de hostadp / dnsmasq, en téléchargeant les librairies idoines et en modifiant notre script d’installation. Vous trouverez ces modifications dans les scripts ansible, en bas de cet article.

Johnny – Les portes du pénitencier

Allons jusqu’au bout de la démarche : pour l’instant votre Pi est ouvert aux quatre vents. Nous allons donc renforcer sa sécurité en durcissant quelque peu nos règles.

Utiliser une clé SSH plutôt qu’un user / mot de passe

Il n’est pas ici nécessaire de paraphraser la documentation officielle, très bien réalisée.

Néanmoins, il est possible de réaliser ces opérations directement sur la carte SD, avant même de la monter pour la première fois dans le Pi.

mkdir $RASPBIAN_SD/home/pi/.ssh && touch $RASPBIAN_SD/home/pi/.ssh/authorized_keys && cat ~/.ssh/id_rsa.pub && $RASPBIAN_SD/home/pi/.ssh/authorized_keys && chown -R 1000:1000 $RASPBIAN_SD/home/pi/.ssh
echo "PasswordAuthentication no" && $RASPBIAN_SD/etc/ssh/sshd_config

Identifier le dongle Wifi comme dongle d’admin

Une autre option pour renforcer la sécurité est de ne transformer votre Pi en AccessPoint que dans le cas où le dongle Wifi est identifié en tant que dongle d’administration.
Pour cela, il suffit d’ajouter une ligne dans le fichier $RASPBIAN_SD/etc/udev/rules.d/70-persistent-net.rules. Cette ligne permettra d’identifier votre dongle par son adresse MAC, et de lui associer un réseau, dans notre cas adm-wlan0.

Par exemple :
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0f:13:38:20:4a", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="adm-wlan0"
Le problème qui se pose alors est qu’il est délicat de trouver l’adresse MAC du dongle sans monter le réseau. Qu’à cela ne tienne, il nous suffit de modifier ces valeurs après le premier démarrage de notre Pi.
#!/bin/bash
 
VAR_FB=/var/lib/first-boot-setup
 
if [[ ! -d $VAR_FB ]] ; then
  mkdir $VAR_FB
fi
 
# checking if we already ran this script
if [[ -f $VAR_FB/initialized ]] ; then
  logger -t "first boot" "first boot setup already done, skipping"
  echo "first boot setup already done, skipping"
else
  chown -R pi:pi /home/pi/.ssh 
  dpkg -i /var/tmp/libmnl0*.deb
  dpkg -i /var/tmp/libnetfilter*.deb
  dpkg -i /var/tmp/libnl-route*.deb
  dpkg --force-confold -i /var/tmp/dnsmasq-base*.deb
  dpkg --force-confold -i /var/tmp/dnsmasq_*.deb
  dpkg --force-confold -i /var/tmp/hostapd*.deb
 
  echo 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%MAC%", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="wlan*", NAME="adm-wlan42"' &gt;&gt; /etc/udev/rules.d/70-persistent-net.rules
  sed -i "s/%MAC%/$(cat /sys/class/net/wlan0/address)/g" /etc/udev/rules.d/70-persistent-net.rules
  sed -i "s/wlan0/adm-wlan42/g" /etc/network/interfaces
  sed -i "s/#hostapd/hostapd/g" /etc/network/interfaces 
  sed -i "s/wlan0/adm-wlan42/g" /etc/dnsmasq.conf
  sed -i "s/wlan0/adm-wlan42/g" /etc/hostapd.conf
  touch $VAR_FB/initialized
   
  ifup adm-wlan42
 
  logger -t "first boot" "first boot setup done !"
  echo "first boot setup done !"
  reboot
fi
 
exit 0

Le réseau adm-wlan0 apparait uniquement lorsque le dongle d’aministration est introduit dans le Pi.

Daft Punk – Robot Rock

Cet article ne serait bien sûr pas complet sans une petite dose de DevOps / automatisation. Vous pourrez donc trouver sur Github les scripts ansible correspondant aux différentes étapes mises en œuvre ici.

Et si vous voulez être parfait, je ne saurais que trop vous conseiller d’appliquer la recette sshd suivante.

Vous pouvez maintenant en 3 minutes monter votre AccessPoint.

Insérez la carte SD, et tapez les commandes suivantes (adaptées à votre sauce) :

mkdir workdir; cd workdir
wget https://downloads.raspberrypi.org/raspbian_lite_latest
unzip *.zip
diskutil unmountDisk /dev/disk2
sudo dd bs=1m if=./2015-11-21-raspbian-jessie-lite.img of=/dev/rdisk2
mkdir /mnt/jessie
sudo fuse-ext2 /dev/disk2s2 /mnt/jessie -o rw+
git clone https://github.com/xebia-france/raspberry-pi-ap ; cd raspberry-pi-ap
sudo ansible-playbook -i "localhost," -c local -e 'RASPBIAN_SD=/mnt/jessie WIFI_PASS=password' piAP.yml
diskutil unmountDisk /dev/disk2

Les Charlots – Merci Patron

Merci à Aurélien Maury (@aurelienmaury) de WeScale pour son aide précieuse sur Ansible.
Pablo Lopez
Pablo est directeur technique au sein de Xebia. Opérationnel par goût, il intervient sur une large variété de missions, de l'analyse de performances en production au conseil en architecture logicielle.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *