This article provides scripts to automate:

  • the installation of Raspbian on Raspberry Pi via a homemade bash script
  • a minimal configuration and security hardening of Raspbian via Ansible with a homemade role.

Installation of Raspbian

Before starting, place yourself in a working directory, for example ~/rpi Then insert the microSD card (via an adapter for example) on your machine and locate the path of the microSD The dmesg or lsblk tools help with this localization

## Dans ces exemples la microSD a été détectée sur sdd ce qui donne comme chemin /dev/sdd ## via dmesg jls42@boo:~/rpi$ sudo dmesg |tail [94655.145112] scsi host8: usb-storage 1-1.2:1.0 [94656.175566] scsi 8:0:0:0: Direct-Access Generic USB SD Reader 1.00 PQ: 0 ANSI: 0 CCS [94656.176298] sd 8:0:0:0: Attached scsi generic sg4 type 0 [94656.177494] sd 8:0:0:0: [sdd] 62333952 512-byte logical blocks: (31.9 GB/29.7 GiB) [94656.178010] sd 8:0:0:0: [sdd] Write Protect is off [94656.178014] sd 8:0:0:0: [sdd] Mode Sense: 4b 00 00 08 [94656.178638] sd 8:0:0:0: [sdd] No Caching mode page found [94656.178647] sd 8:0:0:0: [sdd] Assuming drive cache: write through [94656.182648] sdd: sdd1 sdd2 [94656.185135] sd 8:0:0:0: [sdd] Attached SCSI removable disk ## ou via lsblk jls42@boo:~/rpi$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT [...] sdd 8:48 1 29,7G 0 disk ├─sdd1 8:49 1 43,9M 0 part └─sdd2 8:50 1 1,7G 0 part

Then you can install Raspbian on the microSD for example via install_raspbian.sh During this installation, a mount point will be created /mnt/sdd

#!/bin/bash # Ici on configure le chemin de la microSD # et le point de montage nécessaire à la bonne exécution du script msd_fs="/dev/sdd" mountpoint="/mnt/sdd" [ -d ${mountpoint} ] || mkdir ${mountpoint} [ -b ${msd_fs} ] || { echo "${msd_fs} non disponible" ; exit 1 ;} #raspbian_version="2018-06-27-raspbian-stretch-lite.zip" raspbian_version="" if [ -z ${raspbian_version} ] then raspbian_version=$(curl -s https://downloads.raspberrypi.org/raspbian_lite_latest | \ grep "raspbian_lite"| perl -nle 'print $1 if /.*href=".*images\/.*\/([0-9].*)"/') if [ -e ${raspbian_version} ] then echo "La dernière image de Raspbian est déjà présente" else echo "Téléchargement de la dernière image de Raspbian" curl -s -L https://downloads.raspberrypi.org/raspbian_lite_latest --output ${raspbian_version} fi fi echo -e "Déploiement de ${raspbian_version} to ${msd_fs}" time unzip -p ${raspbian_version} | sudo dd of=${msd_fs} bs=4M conv=fsync && \ echo -e "Montage de ${msd_fs}1 to ${mountpoint}" && \ sudo mount ${msd_fs}1 ${mountpoint} && \ echo -e "Activation du SSH sur Rasbpian" && \ sudo touch ${mountpoint}/ssh && \ echo -e "Vérification de l'activation SSH" && \ sudo ls -l ${mountpoint}/ssh && \ echo -e "Démontage ${msd_fs}1" && \ sudo umount ${mountpoint}

We give it execution rights then we execute it with root rights

chmod 700 install_raspbian.sh sudo ./install_raspbian.sh

Which gives:

jls42@boo:~/rpi$ sudo ./install_raspbian.sh Téléchargement de la dernière image de Raspbian Déploiement de 2018-11-13-raspbian-stretch-lite.zip to /dev/sdd 0+28463 enregistrements lus 0+28463 enregistrements écrits 1866465280 bytes (1,9 GB, 1,7 GiB) copied, 102,911 s, 18,1 MB/s real 1m42,923s user 0m14,203s sys 0m2,851s Montage de /dev/sdd1 to /mnt/sdd Activation du SSH sur Rasbpian Vérification de l'activation SSH -rwxr-xr-x 1 root root 0 déc. 8 22:45 /mnt/sdd/ssh Démontage /dev/sdd1

At this stage the microSD card is prepared, you can insert it directly into your Raspberry Pi.

Configuration and security hardening of Raspbian

Once the microSD card is inserted and the Raspberry Pi is accessible via SSH, we:

  • retrieve the ansible initialization role
  • prepare the ansible playbook
  • launch the Ansible script

Retrieving the ansible-rpi-init ansible role

I developed an ansible role for this automation, here’s how to retrieve it:

git clone git@gitlab.com:jls42/ansible-rpi-init.git roles/ansible-rpi-init

Which gives:

jls42@boo:~/rpi$ git clone https://gitlab.com/jls42/ansible-rpi-init.git roles/ansible-rpi-init Clonage dans 'roles/ansible-rpi-init'... remote: Enumerating objects: 17, done. remote: Counting objects: 100% (17/17), done. remote: Compressing objects: 100% (9/9), done. remote: Total 17 (delta 0), reused 0 (delta 0) Dépaquetage des objets: 100% (17/17), fait.

Creation of the inventory file named inventory In this inventory example the Raspberry Pi has the ip 192.168.1.190

[rpi1] 192.168.1.190 servername=rpi1

Generation of a password hash via mkpasswd and we keep the result for the next action

## ici le mot de passe est 'osef' jls42@boo:~$ mkpasswd --method=sha-512 Mot de passe : $6$KRDQqQeZT$Bu439CILeJqHmwoxCwHXsgTJ5JEQjpZWfzCw6Deggfhip.DGScoCnUSBi.Hqnkh1OZUhTBaQees6GooW.PSLe.

Creation of an Ansible playbook named init_rpi.yml

--- - name: "Initialisation du Rapsberry Pi" hosts: rpi1 remote_user: "pi" roles: - roles/ansible-rpi-init vars: rpi_password: "$6$KRDQqQeZT$Bu439CILeJqHmwoxCwHXsgTJ5JEQjpZWfzCw6Deggfhip.DGScoCnUSBi.Hqnkh1OZUhTBaQees6GooW.PSLe."

Generation of an ssh key pair if you don’t already have one

jls42@boo:~$ [ -f ~/.ssh/id_rsa.pub ] || ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/jls42/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/jls42/.ssh/id_rsa. Your public key has been saved in /home/jls42/.ssh/id_rsa.pub. The key fingerprint is: SHA256:qHhedMjuI0LySVAp2mpFQMozuqBwI00FZo0oHX7rkYI jls42@boo The key's randomart image is: +---[RSA 2048]----+ |.=**. | |*+=o. | |+B+ . | |+++o + o | |Eo* + = S | |*=o= = . | |+=..+ o | | +o.o. | | ..... | +----[SHA256]-----+

At this stage the following files are present

jls42@boo:~/rpi$ tree . ├── 2018-11-13-raspbian-stretch-lite.zip ├── init_rpi.yml ├── install_raspbian.sh ├── inventory └── roles └── ansible-rpi-init ├── defaults │   └── main.yml ├── handlers │   └── main.yml ├── LICENSE ├── meta │   └── main.yml ├── README.md ├── tasks │   └── main.yml ├── tests │   ├── inventory │   └── test.yml └── vars └── main.yml 8 directories, 13 files

Launching Ansible with the init_rpi.yml playbook

## Le mot de passe par défaut est : "raspberry" export ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -k -b -i inventory init_rpi.yml

Which gives

jls42@boo:~/rpi$ ansible-playbook -k -b -i inventory init_rpi.yml SSH password: PLAY [Initialisation du Rapsberry Pi] ****************************************************************************************************************************************************************************************************** TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************************* Saturday 08 December 2018 23:46:18 +0100 (0:00:00.050) 0:00:00.050 ***** ok: [192.168.1.190] TASK [roles/ansible-rpi-init : Mise à jour raspbian] *************************************************************************************************************************************************************************************** Saturday 08 December 2018 23:46:22 +0100 (0:00:03.502) 0:00:03.553 ***** changed: [192.168.1.190] TASK [roles/ansible-rpi-init : Configuration du nom] *************************************************************************************************************************************************************************************** Saturday 08 December 2018 23:47:53 +0100 (0:01:31.114) 0:01:34.667 ***** changed: [192.168.1.190] TASK [roles/ansible-rpi-init : Ajoute le nom du serveur dans le fichier /etc/hosts] ******************************************************************************************************************************************************** Saturday 08 December 2018 23:47:55 +0100 (0:00:01.944) 0:01:36.612 ***** changed: [192.168.1.190] TASK [roles/ansible-rpi-init : Ajoute la clef publique] ************************************************************************************************************************************************************************************ Saturday 08 December 2018 23:47:56 +0100 (0:00:01.031) 0:01:37.643 ***** changed: [192.168.1.190] TASK [roles/ansible-rpi-init : Mise à jour du mot de passe de l'utilisateur pi] ************************************************************************************************************************************************************ Saturday 08 December 2018 23:47:57 +0100 (0:00:01.183) 0:01:38.826 ***** changed: [192.168.1.190] TASK [roles/ansible-rpi-init : Redémarrage] ************************************************************************************************************************************************************************************************ Saturday 08 December 2018 23:47:58 +0100 (0:00:01.249) 0:01:40.075 ***** changed: [192.168.1.190] TASK [roles/ansible-rpi-init : Attente suite au redémarrage] ******************************************************************************************************************************************************************************* Saturday 08 December 2018 23:48:00 +0100 (0:00:01.714) 0:01:41.790 ***** ok: [192.168.1.190] PLAY RECAP ********************************************************************************************************************************************************************************************************************************* 192.168.1.190 : ok=8 changed=6 unreachable=0 failed=0 Saturday 08 December 2018 23:49:00 +0100 (0:01:00.451) 0:02:42.241 ***** =============================================================================== roles/ansible-rpi-init ------------------------------------------------ 158.69s setup ------------------------------------------------------------------- 3.50s ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ total ----------------------------------------------------------------- 162.19s Playbook run took 0 days, 0 hours, 2 minutes, 42 seconds

And there you have it:

  • the access password for the user “pi” has been changed
  • access is now possible without a password
  • the Raspberry Pi has the name indicated in servername (via the inventory file)

Verification

We connect to the Raspberry Pi to confirm good password-free access and good naming

jls42@boo:~/rpi$ ssh pi@192.168.1.190 Linux rpi1 4.14.79-v7+ #1159 SMP Sun Nov 4 17:50:20 GMT 2018 armv7l The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Sat Dec 8 22:47:59 2018 from 192.168.1.42 pi@rpi1:~ $

Enjoy!

This document was translated from fr version to en language using the claude-3-opus-20240229 model. For more information on the translation process, see https://gitlab.com/jls42/ai-powered-markdown-translator