Dans cet article, [Se connecter pour voir le lien] explique comment créer une distribution GNU/Linux basée sur Debian pour un projet personnalisé. Le projet sera, pour l’exemple, un point d’accès connecté à un serveur VPN distant.
L’intérêt d’avoir un système d’exploitation configuré pour un projet précis est d’avoir un système qui fait uniquement ce qu’on attend de lui et qui sera moins sujet aux bugs.
Il sera moins sujets aux bugs car on y installera uniquement les paquets dont on aura besoin.
Pour créer la distribution pour le projet on va faire un chroot d’un environment « arm ».
Chrooter ou « chroot » signifie « Change root »
Dans quels cas utilise-t-on le chroot ?
- Pour sécuriser un environnement de production ( ex. les serveurs sftp, ssh, … ).
- Pour créer une distribution GNU/Linux.
Matériel requis
- N’importe quel modèle de Raspberry pi disposant d’un port ethernet,
- Une carte MicroSD de 2GO,
- Une clé Wi-Fi compatible avec le kernel linux ( Le Raspberry pi 3 en a déjà une ),
- Une configuration VPN valide qui vous permet d’utiliser le logiciel Openvpn.
Le choix du VPN
On a choisi [Se connecter pour voir le lien].
Le prix annuel est très démocratique et les configurations VPN proposées conviennent !
Pour savoir quel service VPN choisir, cliquez sur ce lien : [Se connecter pour voir le lien]
Construction de l’image
Peu recommandé par certains « experts » en sécurité informatique, on vous conseillerait de vous mettre en root en tapant :
Se connecter pour voir le code
Prudence ! à la moindre erreur votre installation pourrait être compromise.
La plupart des commandes seront à copier et coller.
Tout au long du tutoriel vous aurez besoin des droits administrateurs: les commandes commençant par “#” ou “#” sont à exécuter avec les droits du super-user (sans les “#”, bien sûr :nope)
Vous allez avoir besoin de ces paquets pour construire votre image :
Se connecter pour voir le code
Dés que les paquets sont installés, le projet peut commencer. Pour commencer, on initialise les variables d’environnement Bash.
Se connecter pour voir le code
- « KERNEL » le contenu de cette variable dépend directement de votre raspberry pi. On utilise un Raspberry pi 2 donc la variable doit impérativement contenir » kernel7 « . Si vous utilisez un Raspberry pi 3 tout dépend, si vous souhaitez l’utiliser en 64 bit ou en 32 bit. Si vous voulez l’utiliser en 64 bit, la variable doit contenir « kernel8 », si vous voulez l’utiliser en 32 bit, la variable doit contenir « kernel7 ». Si vous utilisez un Raspberry b, b+, A, A+ et Zero, le contenu de la variable sera « kernel ».
- NPROC, est une variable très utile. Elle permet de compter les cœurs du processeur de votre système et de les utiliser avec la commande « make ».
Téléchargeons le firmware du Raspberry pi :
Se connecter pour voir le code
Ensuite téléchargeons le kernel Raspberry pi, très important si vous voulez avoir un Debian fonctionnel !
Se connecter pour voir le code
Compiler le kernel
Après avoir téléchargé le kernel, il faut le cross-compiler.
Se connecter pour voir le code
Ensuite on va compiler le kernel. On va compiler le kernel pour le Raspberry pi 2.
Se connecter pour voir le code
La troisième commande pourrait être optionnel. Elle permet de modifier la configuration du Kernel avant de le compiler. On a décidé de retirer le module du Kernel qui permet d’utiliser l’IPv6.
On retire l’IPv6 du kernel car rien n’indique que le VPN de shadeyouvpn.com supporte l’IPv6. En retirant le support de l’IPv6 on minimise les risques de leaks de données ! Voici les étapes à suivre pour retirer le support de l’IPv6 du kernel :
Il faut aller dans le menu » Networking Support » en tapant sur enter
ensuite aller dans le sous menu » Networking options « .
Il faut exclure le module » The IPv6 protocol » en tapant sur « n »
Si vous comptez utiliser un kernel 64 bit pour votre Raspberry pi 3, la variable CROSS_COMPILE doit contenir « aarch64-linux-gnu- »
et le fichicher de configuration à utiliser est « bcmrpi3_defconfig ».
Pour les autres Raspberry pi, les variables sont les mêmes que pour le Raspberrry pi 2 mais le fichier de configuration est « bcmrpi_defconfig »
Construction du fichier image
Initialisons les variables pour créer le fichier image:
Se connecter pour voir le code
Maintenant, nous allons créer le fichier image vide et le monter.
`# qemu-img create -f raw ${IMGFILE} 850M > /dev/null
(echo “n”; echo “p”; echo “1”; echo “2048”; echo “+21M”; echo “n”; echo “p”; echo “2”; echo "“; echo ”"; echo “t”; echo “1″; echo “c”; echo “w”) | fdisk ${IMGFILE} > /dev/null
# LOOPDEVS=$(sudo kpartx -avs ${IMGFILE} | awk ‘{print $3}’)
# LOOPDEVBOOT=/dev/mapper/$(echo ${LOOPDEVS} | awk ‘{print $1}’)
# LOOPDEVROOTFS=/dev/mapper/$(echo ${LOOPDEVS} | awk ‘{print $2}’)
# mkfs.vfat ${LOOPDEVBOOT}
# mkfs.ext4 ${LOOPDEVROOTFS}
# fatlabel ${LOOPDEVBOOT} Boot
# e2label ${LOOPDEVROOTFS} Debian
# mkdir -p ${MNTROOTFS}
# mount ${LOOPDEVROOTFS} ${MNTROOTFS}`
Le Chroot
On va chrooter Debian et le paramétrer.
`# qemu-debootstrap –keyring /usr/share/keyrings/debian-archive-stretch-stable.gpg –include=ca-certificates –arch=armhf stretch ${MNTROOTFS} [Se connecter pour voir le lien]
# mount ${LOOPDEVBOOT} ${MNTBOOT}
# mount -o bind /proc ${MNTROOTFS}proc
# mount -o bind /dev ${MNTROOTFS}dev
# mount -o bind /dev/pts ${MNTROOTFS}dev/pts
# mount -o bind /sys ${MNTROOTFS}sys
# mount -o bind /tmp ${MNTROOTFS}tmp
# cp $(which qemu-arm-static) ${MNTROOTFS}usr/bin/
# chroot ${MNTROOTFS}`
Si vous chrootez pour le rpi3 en 64 bit il faudra changer l’argument « –arch=arm64 » de qemu-deboostrap et changer l’avant dernière commande:
Se connecter pour voir le code
dès que le chroot est initialisé,
Chroot réussi !
Il faudra installer les paquets adéquats.
Mettez à jour, les listes des fichiers sources qui vous permettront d’installer les paquets:
Se connecter pour voir le code
Enlevez les paquets inutiles pour le projet
Se connecter pour voir le code
Installez les paquets
`# apt-get install -y usbutils bash-completion isc-dhcp-client isc-dhcp-common curl net-tools iputils-ping busybox-syslogd psmisc tar tcpd usbutils wireless-regdb wireless-tools git
# apt-get install -y console-common console-data util-linux ntp dnsutils locales sudo udev kmod ethtool iptables lsb-base lsb-release wpasupplicant nano rsync ssh bash-completion netbase unzip
# apt-get install -y console-setup console-setup-linux network-manager isc-dhcp-server hostapd openvpn wget libnl-route-3-200 libnl-3-200 libnl-genl-3-200 iw crda libssl-dev ifupdown iproute2 `
Ajoutez votre utilisateur dans les groupes adéquats et donnez lui un mot de passe
Se connecter pour voir le code
et éventuellement paramétrez l’encodage si ce type d’erreur vous dérange
Se connecter pour voir le code
Tapez cette commande:
Se connecter pour voir le code
Choisissez la langue. Tapez sur espace pour la sélectionner:
Ici, on a choisi l’anglais américain avec l’encodage UTF-8 pour des raisons de facilités.
Si ces commandes ne fonctionnent pas, vous pouvez aussi utiliser « raspi-config ». Cet utilitaire sera aussi utilisé quand l’image sera flashé sur la carte SD.
Se connecter pour voir le code
Si cette erreur est affichée
Se connecter pour voir le code
Faites ce que la console vous dit et retapez la commande initiale !
Se connecter pour voir le code
Dés que « raspi-config » a été installé, sélectionnez la langue de la console de votre choix.
Entrez dans le sous menu « Change Locale ».
Le sous-menu « Change TimeZone » est très important.
L’encryptage VPN pour fonctionner à besoin que l’horloge du client soit la plus précise possible. Si l’horloge du client est totalement désynchronisée , le serveur VPN va rejeter le client qui voudra s’y connecter.
Choisissez votre continent
Et votre Fuseau horaire
Votre image est maintenant parfaitement synchronisé à l’heure d’internet !
Installons maintenant les firmwares propriétaires dans le chroot.
Se connecter pour voir le code
On assigne un nom d’hôte pour l’image
`# HOSTNAME=vpnrpi
# echo ${HOSTNAME} > tmp-rpi64-script-generated-hostname
# cp tmp-rpi64-script-generated-hostname /etc/hostname
# rm tmp-rpi64-script-generated-hostname
# echo -en "::1 localhost localhost.localdomain ${HOSTNAME}.localdomain\n127.0.0.1 localhost localhost.localdomain ${HOSTNAME}.localdomain\n
The following lines are desirable for IPv6 capable hosts\n::1 ip6-localhost ip6-loopback\nfe00::0 ip6-localnet\nff00::0 ip6-mcastprefix\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n\n127.0.1.1\t${HOSTNAME}\n" >> /etc/hosts`
Éditons le fichier /etc/fstab. Ce fichier va monter le système à chaque boot
`# cat > /tmp/tmp-fstab <<EOF
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults,ro 0 2
/dev/mmcblk0p2 / ext4 defaults 0 1
devpts /dev devpts defaults,gid=5,mode=620,size=1M 0 0
tmpfs /dev/shm tmpfs mode=0777,size=1M 0 0
tmpfs /run tmpfs defaults,noatime,nosuid,mode=1700,size=50m 0 0
tmpfs /tmp tmpfs defaults,noatime,nosuid,mode=1700,size=200m 0 0
tmpfs /sys/fs/cgroup tmpfs defaults,noatime,nosuid,mode=0700,size=1m 0 0
tmpfs /run/user/1000 tmpfs defaults,noatime,nosuid,mode=1700,size=1m 0 0
sysfs /sys sysfs defaults 0 0
EOF
# cp /tmp/tmp-fstab /etc/fstab
# rm /tmp/tmp-fstab`
à la fin du tutoriel ce fichier devra à nouveau être édité. Le système sera remonté en read-only.
Maintenant nous allons éditer le fichier « /etc/systemd/journald.conf »
`# cat > /tmp/tmp_script_generated_journald_conf <<EOF
[Journal]
Storage=volatile
Compress=yes
EOF
# cp /tmp/tmp_script_generated_journald_conf /etc/systemd/journald.conf
# rm /tmp/tmp_script_generated_journald_conf
# systemctl restart systemd-journald.service`
Les logs générés par SystemD seront drastiquement diminués.
Assurons-nous que tous les logs seront redirigés vers le répertoire /tmp qui sera monté dans la ram.
Nous allons effacer tous les sous-répertoires de /var excepté le sous-répertoire /var/lib. Tous les sous-répertoires effacés seront transformés en lien symboliques vers le répertoire /tmp.
Se connecter pour voir le code
Pour les sous-répertoires « /var/lib ». On va faire la même commande avec quelques changements.
Se connecter pour voir le code
Un système d’exploitation a besoin de créer des fichiers temporaires. Sur le long terme, ça endommage la carte SD. Elle devient inutilisable.
La solution est de monter le système en read-only, de monter le dossier « /tmp » sur la ram avec un accès en écriture et en redirigeant tous les fichiers logs dans ce répertoire.
Le répertoire « /usr/lib/tmpfiles.d/ » contient les derniers fichiers qu’on va éditer pour permettre au système d’être en read-only.
`# cat /dev/null > /usr/lib/tmpfiles.d/journal-nocow.conf
# cat <> /usr/lib/tmpfiles.d/journal-nocow.conf
h /tmp/journal - - - - +C
h /tmp/journal/%m - - - - +C
h /tmp/journal/remote - - - - +C
journal-nocow_conf`
`# cat /dev/null > /usr/lib/tmpfiles.d/sudo.conf
# cat <> /usr/lib/tmpfiles.d/sudo.conf
d /tmp/sudo 0711 root root
D /tmp/sudo/ts 0700 root root
system_sudo_conf`
`# cat /dev/null > /usr/lib/tmpfiles.d/systemd.conf
# cat <> /usr/lib/tmpfiles.d/systemd.conf
d /run/user 0755 root root -
F! /run/utmp 0664 root utmp -
d /run/systemd/ask-password 0755 root root -
d /run/systemd/seats 0755 root root -
d /run/systemd/sessions 0755 root root -
d /run/systemd/users 0755 root root -
d /run/systemd/machines 0755 root root -
d /run/systemd/shutdown 0755 root root -
d /run/systemd/netif 0755 systemd-network systemd-network -
d /run/systemd/netif/links 0755 systemd-network systemd-network -
d /run/systemd/netif/leases 0755 systemd-network systemd-network -
d /run/log 0755 root root -
z /run/log/journal 2755 root systemd-journal - -
Z /run/log/journal/%m 2750 root systemd-journal - -
a+ /run/log/journal/%m - - - - d:group:adm:r-x
a+ /run/log/journal/%m - - - - group:adm:r-x
a+ /run/log/journal/%m/.journal - - - - group:adm:r–
z /tmp/journal 2755 root systemd-journal - -
z /tmp/journal/%m 2755 root systemd-journal - -
z /tmp/journal/%m/system.journal 0640 root systemd-journal - -
a+ /tmp/journal - - - - d:group:adm:r-x
a+ /tmp/journal - - - - group:adm:r-x
a+ /tmp/journal/%m - - - - d:group:adm:r-x
a+ /tmp/journal/%m - - - - group:adm:r-x
a+ /tmp/journal/%m/system.journal - - - - group:adm:r–
d /tmp/systemd 0755 root root -
d /tmp/systemd/coredump 0755 root root 3d
systemd_conf`
`# cat /dev/null > /usr/lib/tmpfiles.d/tmp.conf
# cat <> /usr/lib/tmpfiles.d/tmp.conf
D /tmp 1777 root root -
#q /var/tmp 1777 root root 30d
x /tmp/systemd-private-%b-*
X /tmp/systemd-private-%b-*/tmp
tmp_conf`
éditons maintenant on va éditer les fichiers qui permettent d’avoir accès au réseau pendant le démarrage du système
`# sed -i -e “s/TimeoutStartSec=5min/TimeoutStartSec=5sec/” /lib/systemd/system/networking.service
echo “TimeoutStopSec=5s” >> /lib/systemd/system/ifup@.service
# cat > /tmp/tmp-interfaces <<EOF
source-directory /etc/network/interfaces.d
auto lo
iface lo inet loopback
EOF
# mkdir -p /etc/network/
# cp /tmp/tmp-interfaces /etc/network/interfaces
# rm /tmp/tmp-interfaces
# chmod 0600 /etc/network/interfaces`
Pour gagner du temps, on vous propose d’installer directement vos fichiers de configuration de vos VPN. Vous devez aller dans le répertoire /mnt/rpi-chroot-rootfs/ ( référence à la variable « MNTROOTFS » ) et ensuite logiquement aller dans le répertoire /mnt/rpi-chroot-rootfs/home/${RPIUSER}
On peut sortir du chroot et installer les derniers fichiers requis pour le projet ! Dans la parition boot on va installer les modules.
`# exit
# cat > tmp-rpi64-script-generated-config.txt <> tmp-rpi64-script-generated-config.txt
# cp tmp-rpi64-script-generated-config.txt ${MNTBOOT}config.txt
# rm tmp-rpi64-script-generated-config.txt
'# sudo echo -en “dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait\n” >> ${MNTBOOT}cmdline.txt
# ${WRKDIR}linux/scripts/mkknlimg ${WRKDIR}linux/arch/arm/boot/zImage ${MNTBOOT}${KERNEL}.img
# cp ${WRKDIR}linux/arch/arm/boot/dts/*.dtb ${MNTBOOT}
# cd ${WRKDIR}linux
# make INSTALL_MOD_PATH=${MNTROOTFS} modules_install > ${WRKDIR}modules_install.log
# cd ${WRKDIR}`
On peut maintenant démonter le chroot.
Se connecter pour voir le code
Test de l’image
flashez la carte sd en utilisant dd
Se connecter pour voir le code
« of= » est à adapter de votre côté !
insérez la carte sd dans votre Raspberry pi et démarrez le !
Pour trouver l’IP local de votre Raspberry pi, utilisez nmap, angry ip scanner ou autre chose.
Si vous ne trouvez pas d’IP faites un débogage directement à l’écran. Si votre ne rpi démarre pas, réinstallez l’image ou recommencez le tuto :wink
Par contre, si vous avez pu trouver l’IP de votre rpi, on peut maintenant passer à l’étape suivante !
Connectez-vous maintenant au serveur ssh du rpi !
Pour se connecter au serveur ssh vous devez utiliser le login que vous avez créé pendant le chroot et utiliser le mot de passe que vous avez choisi.
Se connecter pour voir le code
Il faut paramétrer le client ( le Raspberrry pi ). On va copier les fichiers avec les extensions « .crt » et « .key » dans le répertoire /etc/openvpn. On va copier un fichier avec l’extension « .ovpn » et la changer en « .conf »
Se connecter pour voir le code
Veuillez noter qu’il pourrait y avoir d’autres fichiers ( *.pem par exemple ) que vous devrez copier dans ce répertoire. Tout dépendra du VPN que vous aurez choisi. Ensuite, il faudra copier le fichier de configuration du VPN que vous désirez utiliser.
Pour les logins tout dépend de votre configuration également. ShadeYouVPN.com utilise des clés plutôt que que des logins. Peut-être que votre cas sera différent, vous allez peut-être devoir créer un fichier « /etc/openvpn/login » qui contient votre mot de passe et votre nom d’utilisateur.
On test la configuration du VPN
Se connecter pour voir le code
Si vous avez ce message
Se connecter pour voir le code
tout fonctionne correctement ! Quittez le programme en tapant Ctrl+c.
Activez le VPN au démarrage
Se connecter pour voir le code
Avant de redémarrer le Raspberrry, on vous propose d’étendre la partition système avec l’utilitaire rasp-config !
Se connecter pour voir le code
L’utilitaire va vous demander si vous voulez redémarrer, cliquer sur « yes ».
Reconnectez-vous et testez votre IP publique.
Se connecter pour voir le code
Si vous obtenez l’IP publique de votre VPN, ça fonctionne ! Le Raspberry pi se connecte bien au VPN au démarrage. Si vous obtenez autre chose ou voir rien du tout, il peut y avoir plusieurs raisons. Soit votre rpi n’a pas accès à internet, votre rpi n’arrive pas à se connecter au serveur VPN ou autre chose.
Si vous avez obtenez l’IP publique de votre vpn, on peut transformer le rpi en un point d’accès Wi-Fi.
Cherchez le nom exact de l’interface qui permet au Raspberry pi d’être connecté au VPN avec
Se connecter pour voir le code
Paramétrage du point d’accès
Pour ne pas perdre de temps, on a décidé de faire un script qui paramètre automatiquement le point d’accès.
Les variables « DEFAULT_IP_ADDRESS », « DEFAULT_IP_ADDRESS », « DEFAULT_WPA2 », « DEFAULT_CHANNEL », « ETHERNET », « WIFI » et « VPN » doivent être initialisées selon vos besoins !
Le script doit être exécuté en tant que root.
Se connecter pour voir le code
Si tout fonctionne correctement, mettez à jours les régles d’iptables.
Exécutez ce script dans votre Raspberry pi, toujours en tant que root !
Se connecter pour voir le code
Ce script va restreindre l’accès au serveur SSH. Seuls les clients du réseau y auront accès.
On édite le fichier « /etc/fstab » pour la dernière fois. On va mettre le système en read-only
`# cat > /tmp/tmp-fstab <<EOF
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults,ro 0 2
/dev/mmcblk0p2 / ext4 defaults,ro 0 1
devpts /dev devpts defaults,gid=5,mode=620,size=1M 0 0
tmpfs /dev/shm tmpfs mode=0777,size=1M 0 0
tmpfs /run tmpfs defaults,noatime,nosuid,mode=1700,size=50m 0 0
tmpfs /tmp tmpfs defaults,noatime,nosuid,mode=1700,size=200m 0 0
tmpfs /sys/fs/cgroup tmpfs defaults,noatime,nosuid,mode=0700,size=1m 0 0
tmpfs /run/user/1000 tmpfs defaults,noatime,nosuid,mode=1700,size=1m 0 0
sysfs /sys sysfs defaults 0 0
EOF
# cp /tmp/tmp-fstab /etc/fstab
# rm /tmp/tmp-fstab
# reboot`
redémarrez votre Raspberry pi !
Si vous ne pouvez pas écrire de fichier à la racine du système, assurez-vous que vous êtes connecté à votre réseau et que vous avez accès à Internet. Tout fonctionne correctement ! Si vous devez momentanément remonter le système en « lecture-écriture »
Se connecter pour voir le code
Pour remettre le système en « read-only »
Se connecter pour voir le code
Article original: [Se connecter pour voir le lien] par [Se connecter pour voir le lien]