Live USB możemy bardzo prosto utworzyć instalując system z użyciem debootastrapa i uzupełniając go w chroocie o jądro, gruba i potrzebne nam narzędzia.
Artykuł ten prezentuje krok po kroku proces budowy własnego live usb. Zaprezentowane w nim zostały polecenia i konfiguracje m.in. związane z następującymi zagadnieniami:
- gpt; efi / uefi; grub;
- montowanie obrazu dysku z pliku (mount disk image from file);
- chroot; montowanie i odmontowywanie specjalnych systemów plików dla chroot; odmontowywanie systemów montowanych z opcją rbind (rbind umount);
- debootstrap;
- optymalizacja dla systemów na pamięciach flash: dane zmienne na tmpfs (ramdysk).
Nie jest to skrypt, który można uruchomić i czekać na gotowy produkt w postaci live USB. Jest to natomiast poradnik, który należy czytać i świadomie wykonywać kolejne podane w nim polecenia. Wymagane jest co najmniej ustawienie zmiennych DEV (wskazującej na urządzenie blokowe na którym prowadzimy instalację) oraz MNT wskazujące na punkt montowania tworzonego rootfs'a. Część prezentowanych ustawień jest opcjonalnych (np. konfiguracja apt'a) i odzwierciedla preferencje autora.
Obraz w pliku
Utworzenie obrazu dysku w pliku, a następnie przekopiowanie go przy pomocy dd na nośnik, jest opcjonalne, ale niekiedy może znacząco przyspieszyć proces instalacji.
dd if=/dev/zero of=usb.img bs=1M count=1913
losetup --partscan --find --show usb.img
Przygotowanie tablicy partycji
# tworzymy tablicę partycji typu gpt
# zasadniczo wystarczył by zwykły MBR z partycją EFI, ale zrobimy hybrydę GPT + MBR
parted $DEV "mklabel gpt"
# tworzy partycję która posłuży do wgrania gruba (musi mieć co najmniej 128 kiB)
# należy zaznaczyć iż nie jest to partycja /boot
# jest to surowe (bez filesystemu) miejsce na dysku gdzie zostanie wgrany
# fragment gruba normalnie wgrywany do MBR
parted $DEV "mkpart grub 0 2MB";
# ustawiamy dla tej partycji flagę "GRUB BIOS partition"
parted $DEV "set 1 bios_grub on";
parted $DEV "mkpart efi 2MB 200MB";
parted $DEV "set 2 boot on";
# resztę dysku możemy podzielić wg uznania,
# tutaj robimy jedną dużą partycję o nazwie rootfs
parted $DEV "mkpart rootfs 200MB 100%";
# przy pomocy gdisk utworzenie hybrid MBR
gdisk $DEV
# r ->
# o
# h ->
# 1 2 3
# n 83 n
# ef y
# 83 n
# o
# w ->
# y
if [ -e ${DEV}1 ]; then
DEVp=${DEV}
elif [ -e ${DEV}p1 ]; then
DEVp=${DEV}p
else
print "ERROR cant find device for partitions on ${DEV}"
fi
mkfs.vfat -F 32 ${DEVp}2
mkfs.xfs ${DEVp}3
Instalacja systemu
# zamontowanie systemu plików
mount ${DEVp}3 ${MNT}
# ustawiamy adres mirrora i instalowaną gałąź Debiana
# (chyba że był wcześniej były ustawione)
MIRROR=${MIRROR:="ftp://ftp.icm.edu.pl/pub/Linux/debian/"}
SUITE="stretch"
# instalujemy system debootstrapem
debootstrap ${SUITE} ${MNT} ${MIRROR}
Chroot
# zamontowanie /proc, /sys i /dev na potrzeby chroot'a
mount -t proc proc $MNT/proc
mount -t sysfs sysfs $MNT/sys
mount -o rbind /dev $MNT/dev
# ustawienie zmiennych środowiskowych
export DEV DEVp MIRROR SUITE
export LC_ALL="C.UTF-8"
# chroot
chroot $MNT
Uwaga: wszystkie następne kroki wykonywane są wewnątrz chroot'a
Podstawowa konfiguracja systemu
# używamy UTF-8
echo 'LANG="C.UTF-8"' > /etc/default/locale;
echo 'set -a; . /etc/default/locale; set +a' > /etc/profile.d/locale.sh
# w /etc/fstab ustawiamy rootfs na read-only, a /tmp na tmpfs
# /var/run i /var/lock są współcześnie linkami do /run na tmpfs
cat /etc/fstab
/dev/disk/by-uuid/$UUID / xfs ro 0 0
tmpfs /tmp tmpfs defaults 0 0
EOF
# katalogi często pisane na ramdysku
# /tmp będzie punktem montowania więc go czyścimy
rm -fr /var/tmp; ln -s /run/tmp /var/tmp
rm -fr /var/log; ln -s /run/log /var/log
cat > etc/tmpfiles.d/on_tmpfs.conf /etc/network/interfaces.d/eth0
echo "iface eth0 inet dhcp">> /etc/network/interfaces.d/eth0
# ssh pozwala na logowanie na root'a i nie jest automatycznie uruchamine
sed -e 's|^[# ]*PermitRootLogin.*$|PermitRootLogin yes|' -i /etc/ssh/sshd_config
systemctl disable ssh.service
# różne ustawienia
systemctl mask hwclock-save.service systemd-random-seed.service udev-finish.service \
systemd-update-utmp-runlevel.service systemd-update-utmp.service
rm /usr/lib/modules-load.d/ipmievd.conf
echo "liveUSB"> /etc/hostname
# hasło root'a
passwd
# konfiguracja użytkownika - skrypty do montowania i odmontowywania chroot'ów
# oraz fałszywa historia linii poleceń (z tym co może nam się przydać w przyszłości)
cat /root/prepareChroot.sh
#!/bin/bash
if [ \$# -ne 2 ]; then
echo USAGE: \$0 device mountpoint
exit
fi
DEV=\$1
MNT=\$2
mount \$DEV \$MNT
mount -t proc proc \$MNT/proc
mount -t sysfs sysfs \$MNT/sys
mount -o rbind /dev \$MNT/dev
chroot \$MNT
EOF
chmod +x /root/prepareChroot.sh
cat /root/umountChroot.sh
if [ \$# -ne 2 ]; then
echo USAGE: \$0 mountpoint
exit
fi
MNT=\$1
umount \$MNT/proc
umount \$MNT/sys
mount --make-rslave \$MNT/dev ; umount -R \$MNT/dev
umount \$MNT
EOF
chmod +x /root/umountChroot.sh
cat /root/.bash_history
mount -o remount,rw /
systemctl start ssh.service
/root/prepareChroot.sh /dev/sdb1 /mnt/1
chroot /mnt/1
/root/umountChroot.sh /mnt/1
EOF
ln -s /root/.bash_history /.bash_history
# samobójstwo bash'a ... zapobiega zapisaniu historii linii poleceń
# skutkuje też wyjściem z chroot'a
kill -9 $BASHPID
Odmontowanie chroot'a
Uwaga: wszystkie następne kroki wykonywane poza chroot-em
umount $MNT/boot/efi/
umount $MNT/run
umount $MNT/tmp
umount $MNT/proc
umount $MNT/sys
mount --make-rslave $MNT/dev
umount -R $MNT/dev
umount $MNT
losetup -d $DEV
Licencja
Copyright (c) 2015-2019, Robert Paciorek <rrp@opcode.eu.org>
To jest wolny i otwarty dokument/oprogramowanie. Redystrybucja, użytkowanie i/lub modyfikacja SĄ DOZWOLONE na warunkach licencji MIT.
This is free and open document/software. Redistribution, use and/or modify ARE PERMITTED under the terms of the MIT license.
The MIT License:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.