123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- #!/bin/env bash
- #############################################################################
- # ██╗ ██╗ ██████╗ ██╗██████╗ ██╗███╗ ██╗███████╗████████╗ █████╗ ██╗ ██╗ ███████╗██████╗
- # ██║ ██║██╔═══██╗██║██╔══██╗ ██║████╗ ██║██╔════╝╚══██╔══╝██╔══██╗██║ ██║ ██╔════╝██╔══██╗
- # ██║ ██║██║ ██║██║██║ ██║ ██║██╔██╗ ██║███████╗ ██║ ███████║██║ ██║ █████╗ ██████╔╝
- # ╚██╗ ██╔╝██║ ██║██║██║ ██║ ██║██║╚██╗██║╚════██║ ██║ ██╔══██║██║ ██║ ██╔══╝ ██╔══██╗
- # ╚████╔╝ ╚██████╔╝██║██████╔╝ ██║██║ ╚████║███████║ ██║ ██║ ██║███████╗███████╗███████╗██║ ██║
- # ╚═══╝ ╚═════╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝
- #########################################################################################################
- # Writen: Bzz
- # Link: https://notabug.org/bzz/void_installer/src/main/void_install.sh
- # License: BSD
- # About: Script for installing Void Linux. Support LVM, LUKS. ROOTFS metod instalation OS.
- # Dependencies: xz, curl
- # Information:
- # [-]=waiting
- # [+]=successful
- # [!]=warning
- # [*]=info
- # [?]=aksing
- #########################################################################################################
- # Colors
- # cl_black=$'\e[30m'
- # cl_red=$'\e[31m'
- # cl_green=$'\e[32m'
- # cl_yellow=$'\e[33m'
- # cl_blue=$'\e[34m'
- # cl_magenta=$'\e[35m'
- # cl_cyan=$'\e[36m'
- # cl_white=$'\e[37m'
- # cl_bright=$'\e[1m'
- # cl_normal=$'\e[0m'
- cl_red=$'\e[31m'
- cl_green=$'\e[32m'
- cl_blue=$'\e[34m'
- cl_normal=$'\e[0m'
- # Environment
- luks_name="voidpc"
- lvm_name="voidpc"
- fs_type="ext4"
- sys_hostname="voidpc"
- sys_language="en_US.UTF-8"
- sys_locale="en_US.UTF-8 UTF-8"
- user_groups="wheel,floppy,cdrom,optical,audio,video,kvm"
- grub_discards="rd.luks.allow-discards"
- rootfs_link="https://repo-default.voidlinux.org/live/current/void-x86_64-ROOTFS-20240314.tar.xz"
- clear
- # Check is script running by root user
- if [ "$(id -u)" != 0 ]; then
- printf "%s[!] Script needs to run as root%s\n" "${cl_red}" "${cl_normal}"
- exit 2
- fi
- # Check dependencies package curl
- if ! [ -x "$(command -v curl)" ]; then
- printf "%s[!] Program curl is not installed!%s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- # Check dependencies package xz
- if ! [ -x "$(command -v xz)" ]; then
- printf "%s[!] Program xz is not installed!%s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- printf "%s######################%s\n" "${cl_blue}" "${cl_normal}"
- printf "%s# Install Void Linux #%s\n" "${cl_blue}" "${cl_normal}"
- printf "%s######################%s\n" "${cl_blue}" "${cl_normal}"
- printf "%s================================%s\n" "${cl_green}" "${cl_normal}"
- printf "%s[*] Selecting disk (DEVICE:SIZE)%s\n" "${cl_green}" "${cl_normal}"
- printf "%s================================%s\n" "${cl_green}" "${cl_normal}"
- # Prompt user to select disk for installation
- run_dev=$(lsblk -psln -o NAME "$(df --output=source / | sed 1d)" | tail -n1)
- PS3="[?] Select disk for installation: "
- # select _ln in $(lsblk -pdno NAME,SIZE | sed 's/ \+/:/g' | grep -v "${run_dev}"); do
- select _ln in $(lsblk -pdno NAME,SIZE | sed 's/ \+/:/g'); do
- if [ -z "${_ln}" ]; then
- printf "%s[!] Wrong selection%s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- printf "[+] Selected disk: <%s>\n" "${_ln}"
- inst_dev=$(echo "${_ln}" | cut -d':' -f1)
- break
- done
- # Unmount all filesystem in /mnt folder
- if grep -q " /mnt " /proc/mounts; then
- if ! umount -qR /mnt; then
- printf "%s[!] Erorr unmounting folder /mnt %s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- fi
- # Check if LVM is active
- _dev=$(lsblk -pnlo NAME,FSTYPE "${inst_dev}" | grep LVM2 | awk '{ print$1 }')
- if [ -n "${_dev}" ]; then
- if lvscan --devices "${_dev}" | grep -q ACTIVE; then
- _vg=$(pvscan --listvg "${_dev}" | awk '{ print$2}')
- vgchange -qan "${_vg}"
- fi
- fi
- # Check if LUKS is open
- _name=$(lsblk -nlo NAME,TYPE "${inst_dev}" | grep "crypt$" | awk '{ print$1}')
- if [ -n "${_name}" ]; then
- if cryptsetup status "${_name}" | grep -q "is active"; then
- cryptsetup close "${_name}"
- fi
- fi
- # Check if luks_name is open
- if cryptsetup status "${luks_name}" | grep -q "is active"; then
- printf "%s[!] LUKS volume <%s> is active%s\n" "${cl_red}" "${luks_name}" "${cl_normal}"
- exit 1
- fi
- # Check if installed device is mounted
- for _dev in $(lsblk -pnlo NAME "${inst_dev}"); do
- if grep -q "${_dev}" /proc/mounts; then
- printf "%s[!] Device <%s> is mounted%s\n" "${cl_red}" "${_dev}" "${cl_normal}"
- exit 1
- fi
- done
- # Promt for script continuation
- read -rp "[?] Install to device <${inst_dev}>: (y/n) " _key
- if [ "${_key}" != "y" ]; then
- printf "%s[!] Aborted!%s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- # Promt separete /boot dir
- read -rp "[?] Folder /boot on separate partition: (y/n) " _key
- if [ "${_key}" == "y" ]; then
- inst_boot="yes"
- fi
- # Wipe disk
- wipefs -aqf "${inst_dev}" >/dev/null &&
- printf "[+] Wipe disk %s\n" "${inst_dev}"
- # Format disklabel as DOS, create partition for LUKS
- if [ "${inst_boot}" == "yes" ]; then
- printf 'label: dos\n, 1G, L, *\n, , L\n' | sfdisk -q "${inst_dev}" &&
- printf "[+] Create disklabel type <DOS> and partition\n"
- inst_dev_boot=$(lsblk -pnlo NAME "${inst_dev}" | sed -n 2p)
- inst_dev_pool=$(lsblk -pnlo NAME "${inst_dev}" | sed -n 3p)
- else
- printf 'label: dos\n, , L, *\n' | sfdisk -q "${inst_dev}" &&
- printf "[+] Create disklabel type <DOS> and partition\n"
- inst_dev_pool=$(lsblk -pnlo NAME "${inst_dev}" | sed 1d)
- fi
- printf "%s=======================%s\n" "${cl_green}" "${cl_normal}"
- printf "%s[*] Users and passwords%s\n" "${cl_green}" "${cl_normal}"
- printf "%s=======================%s\n" "${cl_green}" "${cl_normal}"
- # Grab informations about users and passwords
- read -rsp "[?] Password for user <root>: " root_pass
- printf "\n"
- read -rp "[?] Non-root user: " user_name
- read -rsp "[?] Password for user <${user_name}>: " user_pass
- printf "\n"
- printf "%s========================%s\n" "${cl_green}" "${cl_normal}"
- printf "%s[*] Encrypting partition%s\n" "${cl_green}" "${cl_normal}"
- printf "%s========================%s\n" "${cl_green}" "${cl_normal}"
- read -rsp "[?] Password for encrypting device: " luks_pass
- printf "\n"
- printf "[-] Encrypting partition, wait... "
- # Create LUKS encrypted partition
- if [ "${inst_boot}" == "yes" ]; then
- # Create LUKS type 2
- if echo "${luks_pass}" | cryptsetup -q luksFormat "${inst_dev_pool}"; then
- printf "OK!\n"
- else
- printf "%s[!] ERROR%s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- else
- # Create LUKS type 1, for GRUB support
- if echo "${luks_pass}" | cryptsetup -q --type luks1 luksFormat "${inst_dev_pool}"; then
- printf "OK!\n"
- else
- printf "%s[!] ERROR%s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- fi
- # Open encrypted partition
- printf "[-] Opening volume to </dev/mapper/%s>... " "${luks_name}"
- if echo "${luks_pass}" | cryptsetup open "${inst_dev_pool}" "${luks_name}"; then
- printf "OK!\n"
- else
- printf "%s[!] ERROR%s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- printf "%s=================================%s\n" "${cl_green}" "${cl_normal}"
- printf "%s[*] Creating LVM and file systems%s\n" "${cl_green}" "${cl_normal}"
- printf "%s=================================%s\n" "${cl_green}" "${cl_normal}"
- # Create LVM in encrypted partition, and create file systems
- pvcreate /dev/mapper/${luks_name} >/dev/null &&
- printf "[+] PV </dev/mapper/%s> successfully created\n" "${luks_name}"
- vgcreate ${lvm_name} /dev/mapper/${luks_name} >/dev/null &&
- printf "[+] VG <%s> successfully created\n" "${lvm_name}"
- # Reading size for LVs
- inst_dev_size=$(lsblk -pdno SIZE "${inst_dev_pool}" | sed 's/ \+//g')
- printf "[+] Max size for LV partition - <%s>\n" "${inst_dev_size}"
- read -rp "[?] Size{M,G,T,P} for LV-root (empty - all space): " lvm_root_size
- # Check if size is correct
- if [ -n "${lvm_root_size}" ]; then
- echo "${lvm_root_size}" | grep -qE "^[0-9]+(\.[0-9])?[MGTP]$"
- if [ $? == 1 ]; then
- printf "%s[!] Not correct size%s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- # Creating LVs
- lvcreate --name root -L "${lvm_root_size}" "${lvm_name}" >/dev/null &&
- printf "[+] Logical volume <root> created\n"
- lvcreate --name home -l 100%FREE ${lvm_name} >/dev/null &&
- printf "[+] Logical volume <home> created\n"
- # Creating FS for LVs
- printf "[-] Creating FS for LV root, wait... "
- mkfs.${fs_type} -qL root /dev/${lvm_name}/root && printf "OK!\n"
- printf "[-] Creating FS for LV home, wait... "
- mkfs.${fs_type} -qL home /dev/${lvm_name}/home && printf "OK!\n"
- else
- lvcreate --name root -l 100%FREE ${lvm_name} >/dev/null &&
- printf "[+] Logical volume <root> created\n"
- printf "[-] Creating FS for LV root, wait... "
- mkfs.${fs_type} -qL root /dev/${lvm_name}/root && printf "OK!\n"
- fi
- # Creating FS for /boot
- if [ "${inst_boot}" == "yes" ]; then
- printf "[-] Creating FS for boot, wait... "
- mkfs.ext2 -qFL boot "${inst_dev_boot}" && printf "OK!\n"
- fi
- printf "%s========================%s\n" "${cl_green}" "${cl_normal}"
- printf "%s[*] Mounting FileSystems%s\n" "${cl_green}" "${cl_normal}"
- printf "%s========================%s\n" "${cl_green}" "${cl_normal}"
- # Mount LVM's
- if [ -n "${lvm_root_size}" ]; then
- mount /dev/${lvm_name}/root /mnt &&
- printf "[+] Mount LV root to /mnt\n"
- mkdir /mnt/home
- mount /dev/${lvm_name}/home /mnt/home &&
- printf "[+] Mount LV home to /mnt/home\n"
- else
- mount /dev/${lvm_name}/root /mnt &&
- printf "[+] Mount LV root to /mnt\n"
- fi
- # Mount boot
- if [ "${inst_boot}" == "yes" ]; then
- mkdir /mnt/boot
- mount "${inst_dev_boot}" /mnt/boot &&
- printf "[+] Mount boot to /mnt/boot\n"
- fi
- # Mount pseudo FS's
- for _fs in dev proc sys; do
- mkdir /mnt/${_fs}
- mount --rbind "/${_fs}" "/mnt/${_fs}"
- mount --make-rslave "/mnt/${_fs}"
- printf "[+] Mount /%s to /mnt/%s\n" "${_fs}" "${_fs}"
- done
- printf "%s====================%s\n" "${cl_green}" "${cl_normal}"
- printf "%s[*] ROOTFS preparing%s\n" "${cl_green}" "${cl_normal}"
- printf "%s====================%s\n" "${cl_green}" "${cl_normal}"
- # Download and install base packages
- printf "[-] Downloading rootfs tarball, wait... "
- if curl -s -o void.tar.xz ${rootfs_link}; then
- printf "OK!\n"
- else
- printf "%s[!] ERROR!!%s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- printf "[-] Extract files from archive, wait... "
- if tar xf void.tar.xz -C /mnt; then
- printf "OK!\n"
- else
- printf "%s[!] ERROR!!%s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- # Remove ROOTFS file
- rm -f void.tar.xz >/dev/null
- # Copy the DNS configuration
- mkdir -p /mnt/etc
- cp /etc/resolv.conf /mnt/etc/
- printf "%s=================================%s\n" "${cl_green}" "${cl_normal}"
- printf "%s[*] Chroot: install and configure%s\n" "${cl_green}" "${cl_normal}"
- printf "%s=================================%s\n" "${cl_green}" "${cl_normal}"
- # Change ownership and permissions of root directory
- chroot /mnt chown root:root /
- chroot /mnt chmod 755 /
- # Installing base system
- printf "[-] Syncing system and update xbps, wait..."
- if chroot /mnt xbps-install -Suy xbps >/dev/null; then
- printf "OK\n"
- else
- printf "%s[!] ERROR!!%s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- printf "[-] Updating system, wait..."
- if chroot /mnt xbps-install -uy >/dev/null; then
- printf "OK\n"
- else
- printf "%s[!] ERROR!!%s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- printf "[-] Installing base system, wait..."
- if chroot /mnt xbps-install -y base-system lvm2 cryptsetup grub >/dev/null; then
- printf "OK\n"
- else
- printf "%s[!] ERROR!!%s\n" "${cl_red}" "${cl_normal}"
- exit 1
- fi
- printf "[-] Removing package base-voidstrap, wait... "
- if chroot /mnt xbps-remove -y base-voidstrap >/dev/null; then
- printf "OK\n"
- else
- printf "%s[!] ERROR!!%s\n" "${cl_red}" "${cl_normal}"
- fi
- # Add and set passwords for users
- printf "[+] Set password for user <root>\n"
- printf "%s\n%s" "${root_pass}" "${root_pass}" | passwd -R /mnt root
- printf "[-] Adding user <%s>... " "${user_name}"
- chroot /mnt useradd "${user_name}" && printf "OK!\n"
- printf "[-] Modifying user <%s>... " "${user_name}"
- chroot /mnt usermod -aG "${user_groups}" "${user_name}" && printf "OK!\n"
- printf "[+] Set password for user <%s>\n" "${user_name}"
- printf "%s\n%s" "${user_pass}" "${user_pass}" | passwd -R /mnt "${user_name}"
- # Set hostname and language/locale
- echo "${sys_hostname}" >/mnt/etc/hostname
- printf "[+] Set hostname <%s>\n" "${sys_hostname}"
- echo "LANG=${sys_language}" >/mnt/etc/locale.conf
- printf "[+] Set language <%s>\n" "${sys_language}"
- # libc-locales are only applicable for glibc installations
- echo "${sys_locale}" >>/mnt/etc/default/libc-locales
- printf "[-] Reconfiguring locale to <%s>, wait... " "${sys_locale}"
- chroot /mnt xbps-reconfigure -f glibc-locales >/dev/null && printf "OK!\n"
- # Modify file /etc/fstab in chroot
- if [ "${inst_boot}" == "yes" ]; then
- boot_uuid="UUID=\"$(lsblk -no UUID "${inst_dev_boot}")\""
- sed -n "s|${inst_dev_boot}|${boot_uuid}|; s|/mnt/boot|/boot|p" /proc/mounts >> \
- /mnt/etc/fstab
- fi
- grep "/dev/mapper/${lvm_name}" /proc/mounts |
- awk '$2 == "/mnt" { $2 = "/" } $2 == "/mnt/home" { $2 = "/home" } 1' >> \
- /mnt/etc/fstab
- printf "[+] Update /etc/fstab\n"
- # Enable LUKS in GRUB
- echo "GRUB_ENABLE_CRYPTODISK=y" >>/mnt/etc/default/grub
- luks_uuid=$(lsblk -ndo UUID "${inst_dev_pool}")
- kernel_params="rd.lvm.vg=${lvm_name} rd.luks.uuid=$luks_uuid ${grub_discards}"
- sed -i "s/\(GRUB_CMDLINE_LINUX_DEFAULT=\"\)/\1${kernel_params} /" \
- /mnt/etc/default/grub
- printf "[+] Enable LUKS in GRUB\n"
- # Generate keyfile to automatically unlock the encrypted volume on boot.
- dd bs=1 count=64 if=/dev/urandom of=/mnt/root/volume.key status=none
- echo "${luks_pass}" | cryptsetup -q luksAddKey "${inst_dev_pool}" /mnt/root/volume.key
- # Change the permissions to protect generated the keyfile
- chmod 000 /mnt/root/volume.key
- chmod -R g-rwx,o-rwx /mnt/root/volume.key
- printf "%s\tUUID=%s\t/root/volume.key\tluks\n" "${luks_name}" "${luks_uuid}" >> \
- /mnt/etc/crypttab
- # Configure for dracut
- printf "install_items+=\" /root/volume.key /etc/crypttab \"\n" > \
- /mnt/etc/dracut.conf.d/10-crypt.conf
- # Install GRUB bootloader
- printf "[-] Installing GRUB to <%s>, wait...\n" "${inst_dev}"
- chroot /mnt grub-install "${inst_dev}" >/dev/null
- # Ensure an initramfs is generated
- printf "[-] Reconfigure system, wait...\n"
- chroot /mnt xbps-reconfigure -fa >/dev/null
- printf "[+] Done!\n"
- printf "%s=======================%s\n" "${cl_green}" "${cl_normal}"
- printf "%s[*] Swap file configure%s\n" "${cl_green}" "${cl_normal}"
- printf "%s=======================%s\n" "${cl_green}" "${cl_normal}"
- read -rp "[?] Use swap file: (y/n) " _key
- if [ "${_key}" == "y" ]; then
- # Adding swap file
- printf "[-] Creating swap file 2Gb..."
- if dd if=/dev/zero of=/mnt/swapfile bs=2048 count=1000000; then
- printf "OK\n"
- else
- printf "[!] Error creating swap file\n"
- exit 1
- fi
- # Set up a Linux swap area
- mkswap -q /mnt/swapfile
- chmod 600 /mnt/swapfile
- printf "[+] Set up a swap file\n"
- # Adding swap file to /etc/fstab
- swap_uuid=$(swaplabel /mnt/swapfile | sed 's/:\s*/=/')
- printf "%s none swap sw 0 0\n" "${swap_uuid}" >> /mnt/etc/fstab
- printf "[+] Adding swap file to /etc/fstab\n"
- else
- printf "[+] Skipping swap file configure\n"
- fi
- printf "%s#######################%s\n" "${cl_blue}" "${cl_normal}"
- printf "%s# Finish install Void #%s\n" "${cl_blue}" "${cl_normal}"
- printf "%s#######################%s\n" "${cl_blue}" "${cl_normal}"
- printf "[?] Unmount newly created Void installation: (y/n) "
- read -r _key
- if [[ "${_key}" == "y" ]]; then
- umount -R /mnt # Unmount root volume
- vgchange -an "${lvm_name}" # Deactivate volume group
- cryptsetup close ${luks_name} # Close LUKS encrypted partition
- fi
|