%
Puffy image/svg+xml Puffy 2019-06-14 Stéphane HUC OpenBSD Team Inkscape Puffy OpenBSD https://www.openbsd.org/art4.html English "Puffy", it's a symbol of OpenBSD

OpenBSD : monter un disque dur chiffré automatiquement

Article publié, le et modifié le
6 minutes de lecture

Cet article contient 1110 mots.
Source brute de l'article :
Commit version : 698e16e

Description

Non, je ne vais pas vous apprendre à créer un disque dur chiffré sous OpenBSD - la FAQ officielle (en anglais), ou la version traduite (en Français), vous l’apprendra mieux que moi-même !

Convention et étapes de base

Vous vous êtes assuré que le disque dur est connecté… électriquement, et soit en USB, en SATA, etc… Admettons que celui-ci soit reconnu par le système en tant que sd0.

L’étape 0 - de base - est d’enregistrer la passphrase dans un fichier, et de lui donner les droits nécessaires au bon fonctionnement de bioctl : 0600.

Par convention, nous appellerons ce fichier /root/crypt_passwd.

disk="sd0"
file_passwd="/root/crypt_passwd"
file_tmp="/tmp/raid.info"

Une méthode plus sûre est l’usage d’une clé USB dédié au déchiffrement. À savoir qu’il est possible d’utiliser une seule et même clé pour le chiffrement de plusieurs disques, une partition par chiffrement.

duid

La première étape est d’obtenir le duid - c’est l’identifiant du disk, fourni par disklabel - relatif à notre périphérique sd0.

duid="$(disklabel ${disk0} | awk -F':' '/duid/ { gsub(/[[:space:]]*/, "", $2) ; printf "%s",$2 }')"

Que fait awk dans les détails ? Il recherche la ligne comportant la mention duid, et supprime tout espace, pour enfin afficher le résultat recherché, sans retour à la ligne !

numéro partition RAID

Obtenons la lettre de partition relative à la partition RAID - en réalité, la partition chiffrée par bioctl.

Code : sh

# get partition's letter
s="$(disklabel ${disk} | awk -F':' '/RAID/ { gsub(/[[:space:]]*/, "", $1); printf "%s",$1 }' )"
slide="${duid}.$s"

identifiant disque

Attachons le périphérique chiffré à un périphérique softraid0 :

bioctl -c C -l ${slide} -p ${file_passwd} softraid0 > ${file_tmp}

Le fichier temporaire contiendra très certainement une mention, telle que la suivante : softraid0: CRYPTO volume attached as sd2 - néanmoins cela dépend du fait d’avoir d’autres périphériques connectés, soit sur les ports SATA, USB, etc…

De toute façon, quelque soit l’écriture restituée dans le fichier temporaire, nous récupérerons l’identifiant du périphérique attaché, de manière "dynamique".

device="$(awk '/CRYPTO/ { printf "%s",$6 }' ${file_tmp})"

Dans cet exemple, la valeur obtenue sera sd2.

Maintenant, obtenons à nouveau la lettre de partition, mais cette fois-ci du périphérique attaché, pour construire les variables nécessaires :

Code : sh

s="$(disklabel ${device} | awk -F':' '/'4.2BSD/ { gsub(/[[:space:]]*/, "", $1); printf "%s",$1 }' )"

partition="${disk}$s"
slide="${duid}.$s"

mount

mkdir -p /mnt/${device}
mount -o noatime,nodev,noexec,nosuid,rw,softdep /dev/${partition} /mnt/${device}

Voilà, normalement nous avons accès au périphérique chiffré attaché et monté !

Il n’y a plus qu’à le remplir…

FS check

Si le montage ne se fait pas correctement, exécutons une vérification du système de fichier :

fsck -y /dev/${partition}

Si c’est OK, essayez de remonter la partition vers le répertoire choisi, avec la commande mount ci-dessus.

umount

Le démontage et le détachement du périphérique se fait très simplement :

umount -f /mnt/${device} bioctl -d ${device}

Pense-bête pour supprimer le fichier temporaire qui n’est plus nécessaire :

rm -fP "${file_tmp}"

TL;DR

Voici le script complet, dont je me sers, pour monter et démonter automatique un périphérique chiffré avec bioctl dès le démarrage du système OpenBSD.

Il faut l’utiliser ainsi :

  • pour monter le périphérique : ./mount_crypt_hd mount - créez le fichier /etc/rc.local et appelez le script de la manière à le monter…
  • pour démonter le périphérique proprement : ./mount_crypt_hd umount - créez le fichier /etc/rc.shutdown et appelez le script de la manière à le démonter…

Fichier : mount_crypt_hd

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/bin/sh
#set -x

###
#
# Author: Stéphane HUC
# mail: devs@stephane-huc.net
# gpg:fingerprint: CE2C CF7C AB68 0329 0D20  5F49 6135 D440 4D44 BD58
#
# License: BSD Simplified
#
# Github:
#
# Date: 2018/10/03
#
###

error=0 # DO NOT TOUCH
device=""  # DO NOT TOUCH
dir_nas="/mnt/nas"  # mount point of crypted hd
disk0="sd0" # DO NOT TOUCH
file_passwd="/root/nas" # passwd file of crypted hd
partition=""    # DO NOT TOUCH
s=""    # letter of slide - DO NOT TOUCH
slide=""    # DO NOT TOUCH

################################################################################
###
##
#   FUNCTIONS
##
###
################################################################################
get_device() {
    device="$(awk '/CRYPTO/ { printf "%s",$6 }' ${file_tmp})"
}

get_duid() {
    # get duid info
    duid="$(disklabel ${disk0} | awk -F':' '/duid/ { gsub(/[[:space:]]*/, "", $2) ; printf "%s",$2 }')"
}

get_slide() {
    disk="$1"
    case "${disk}" in
        ${disk0}) pattern="RAID" ;;
        ${device}) pattern="4.2BSD" ;;
    esac

    # get partition's letter
    s="$(disklabel ${disk} | awk -F':' '/'${pattern}'/ { gsub(/[[:space:]]*/, "", $1); printf "%s",$1 }' )"

    partition="${disk}$s"
    slide="${duid}.$s"

    unset disk pattern
}

_mount() {
    [ ! -d ${dir_nas} ] && mkdir -p "${dir_nas}"
    logger "rc.local: mount ${partition} to ${dir_nas}!"
    mount -o noatime,nodev,noexec,nosuid,rw,softdep /dev/${partition} ${dir_nas}
}

mount_crypt_device() {
    get_duid
    get_slide ${disk0}

    file_tmp="/tmp/${duid}.info"

    if [ -n ${duid} ]; then
        # attempt to open HD
        logger "rc.local: bioctl -c C -l ${slide} -p ${file_passwd} "
        if bioctl -c C -l ${slide} -p ${file_passwd} softraid0 > ${file_tmp}; then
            get_device
            echo "*** bioctl attaches from ${slide} to /dev/${device}: OK!"
            chmod 0400 ${file_tmp}

        else
            echo "*** bioctl C from ${slide}: KO!"

        fi

        if [ -r ${file_tmp} ]; then
            get_slide ${device}

            if [ -n ${device} ]; then
                # attempt to mount
                if _mount; then
                    echo "*** Mount ${device} on ${dir_nas}: OK!"

                else
                    error=1
                    echo "*** Mount ${device}: KO!"
                    echo "*** Init a FS check on ${partition}!"
                    logger "rc.local: Can't mount ${device}; attempt FS check on ${partition}!"

                    if fsck -y /dev/${partition}; then
                        echo "*** Fsck seems: OK!"
                        logger "rc.local: FS check on ${partition}: OK!"

                        if _mount; then error=0; fi

                    else
                        echo "*** Fsck seems: KO!"
                        echo "### Can not mount on ${device} crypted HD ${slide}! ###"
                        logger "rc.local: FS check on ${device}: KO! Can't mount-it!"

                    fi

                fi

                if [ ${error} -eq 0 ]; then sync; fi

            fi

        fi

}

_shutdown() {
    get_duid
    file_tmp="/tmp/${duid}.info"
    get_device
    logger "rc.shutdown: umount:${dir_nas}"
    umount -f "${dir_nas}"
    sleep 3
    sync
    logger "rc.shutdown: bioctl -d ${device}"
    bioctl -d ${device}
    rm -fP "${file_tmp}"
}

################################################################################
###
##
#   EXECUTION
##
###
################################################################################

case "$1" in
    "mount") mount_crypt_device ;;
    "umount") _shutdown ;;
esac

Remerciement