This article provides scripts to automate the following:

  • the installation of Raspbian on Raspberry Pi using a homemade bash script
  • a basic configuration and security setup of Raspbian using Ansible with a homemade role.

Raspbian Installation

Before starting, navigate to a working directory, for example ~/rpi
Then insert the microSD card (via an adapter if necessary) into your device and locate the path to the microSD card
Tools such as dmesg or lsblk can help you find it.

## 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  

Next, you can install Raspbian on the microSD card using, for example, install_raspbian.sh
During this installation, a mount point will be created at /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}

Give it execution permissions and then run it with root permissions

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 ready, and you can insert it directly into your Raspberry Pi.

Configuration and Security Setup of Raspbian

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

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

Retrieving the ansible ansible-rpi-init role

I developed an ansible role for this automation, here is 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.

Create an 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

Generate a password hash using mkpasswd and keep the result for the following action

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

Create 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."

Generate 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 point, 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

Running Ansible with the playbook init_rpi.yml

## 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 go:

  • the access password for 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

Connect to the Raspberry Pi to confirm the passwordless access and correct 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 the French version of the blog by the gpt-4-1106-preview model.