344 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			344 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
#!/bin/sh
 | 
						||
 | 
						||
# Vars
 | 
						||
## Define the hard drive to use
 | 
						||
if [ -b '/dev/sda' ]; then
 | 
						||
	hdd="/dev/sda"
 | 
						||
else
 | 
						||
	printf '%b\n' "Please check the hard drive to use"
 | 
						||
	exit 0
 | 
						||
fi
 | 
						||
## Which version of Debian should be installed
 | 
						||
debian_version="buster"
 | 
						||
## Computer hostname
 | 
						||
## If empty, the script will try to get one with nslookup
 | 
						||
new_hostname=""
 | 
						||
## Volume Group name to use for LVM
 | 
						||
vgname="${new_hostname}vg"
 | 
						||
## If the script should manage the partitions (delete, add,…)
 | 
						||
manage_part=0
 | 
						||
## If the script should use BTRFS
 | 
						||
manage_btrfs=1
 | 
						||
## If the script should create extra volume (eg. backup, virt, Proxmox,…)
 | 
						||
manage_extra_lv=0
 | 
						||
## If the script should cipher data with LUKS
 | 
						||
manage_luks=1
 | 
						||
## You need to set a new passphrase after the installation or at least change this one
 | 
						||
luks_passphrase="generic key"
 | 
						||
luks_key_file="/tmp/luks.keyfile.temp"
 | 
						||
luks_pv_name=$(basename "${hdd}"_crypt)
 | 
						||
## If the script should manage everything (partition, package,…) related to grub
 | 
						||
manage_grub=0
 | 
						||
## Colors definition {{{
 | 
						||
BLACK='\033[49;30m'
 | 
						||
BLACKB='\033[49;90m'
 | 
						||
RED='\033[0;31m'
 | 
						||
REDB='\033[1;31m'
 | 
						||
GREEN='\033[0;32m'
 | 
						||
YELLOW='\033[0;33m'
 | 
						||
BLUE='\033[94;49m'
 | 
						||
MAGENTA='\033[0;35m'
 | 
						||
CYAN='\033[36;49m'
 | 
						||
WHITE='\033[0;37m'
 | 
						||
BOLD='\033[1m'
 | 
						||
RESET='\033[0m'
 | 
						||
## }}}
 | 
						||
 | 
						||
## Package to exclude from debootstrap install
 | 
						||
dbs_pkg_exclude="vim-tiny"
 | 
						||
## Package to include to debootstrap install
 | 
						||
dbs_pkg_include="aptitude,btrfs-progs,bzip2,cryptsetup,debconf-i18n,dialog,dmsetup,htop,isc-dhcp-client,isc-dhcp-common,locales,lvm2,openssh-server,pciutils,thin-provisioning-tools,tmux,vim-nox,wget,zsh"
 | 
						||
 | 
						||
# Prepare host system {{{
 | 
						||
apt update
 | 
						||
apt install -y coreutils debootstrap e2fsprogs gawk ipcalc lvm2 thin-provisioning-tools parted util-linux wget || exit 1
 | 
						||
# }}}
 | 
						||
# Partitionning {{{
 | 
						||
if [ "${manage_part}" -eq 0 ]; then
 | 
						||
	## Remove all old partitions {{{
 | 
						||
	for part_number in 1 2 3 4 5 6 7 8; do
 | 
						||
		[ -b "${hdd}""${part_number}" ] && parted "${hdd}" rm "${part_number}"
 | 
						||
	done
 | 
						||
	## }}}
 | 
						||
	## Recreate partition (/boot and LV) {{{
 | 
						||
	### Partition type
 | 
						||
	parted "${hdd}" mklabel gpt || exit 1
 | 
						||
 | 
						||
	if [ "${manage_grub}" -eq 0 ]; then
 | 
						||
		### /boot
 | 
						||
		parted "${hdd}" mkpart primary 0% 512MB || exit 1
 | 
						||
		parted "${hdd}" set 1 boot on
 | 
						||
		sleep 2
 | 
						||
		mkfs.ext3 -F -L boot -- "${hdd}"1 || exit 4
 | 
						||
 | 
						||
		### LV
 | 
						||
		root_part_id="2"
 | 
						||
		parted "${hdd}" mkpart primary 512MB 100% || exit 1
 | 
						||
		parted "${hdd}" set "${root_part_id}" lvm on
 | 
						||
		sleep 2
 | 
						||
	else
 | 
						||
		### LV
 | 
						||
		root_part_id="1"
 | 
						||
		parted "${hdd}" mkpart primary 0% 100% || exit 1
 | 
						||
		parted "${hdd}" set "${root_part_id}" lvm on
 | 
						||
		sleep 2
 | 
						||
	fi
 | 
						||
 | 
						||
	if [ "${manage_luks}" -eq 0 ]; then
 | 
						||
		rm -f -- "${luks_key_file}" && printf '%b' "${luks_passphrase}" > "${luks_key_file}"
 | 
						||
		cryptsetup -c aes-xts-plain64 -s 512 --use-random -y luksFormat "${hdd}${root_part_id}" "${luks_passphrase}" --key-file "${luks_key_file}" || exit 2
 | 
						||
		cryptsetup luksOpen "${hdd}${root_part_id}" "${luks_pv_name}" --key-file "${luks_key_file}" || exit 2
 | 
						||
		pvcreate /dev/mapper/"${luks_pv_name}" || exit 3
 | 
						||
		vgcreate "${vgname}" /dev/mapper/"${luks_pv_name}" || exit 3
 | 
						||
	else
 | 
						||
		pvcreate "${hdd}${root_part_id}" || exit 3
 | 
						||
		vgcreate "${vgname}" "${hdd}${root_part_id}" || exit 3
 | 
						||
	fi
 | 
						||
## }}}
 | 
						||
	## Create Logical Volumes {{{
 | 
						||
	if [ "${manage_btrfs}" -eq 0 ]; then
 | 
						||
		### Create only 1 LV for btrfs base system
 | 
						||
		[ ! -b /dev/mapper/"${vgname}"-root ] && lvcreate -n root -L 70g  "${vgname}"
 | 
						||
	else
 | 
						||
		### Otherwise create differents LVs
 | 
						||
		[ ! -b /dev/mapper/"${vgname}"-home ] && lvcreate -n home -L 20g  "${vgname}"
 | 
						||
		[ ! -b /dev/mapper/"${vgname}"-opt  ] && lvcreate -n opt  -L 2g   "${vgname}"
 | 
						||
		[ ! -b /dev/mapper/"${vgname}"-root ] && lvcreate -n root -L 5g   "${vgname}"
 | 
						||
		[ ! -b /dev/mapper/"${vgname}"-srv  ] && lvcreate -n srv  -L 2g   "${vgname}"
 | 
						||
		[ ! -b /dev/mapper/"${vgname}"-tmp  ] && lvcreate -n tmp  -L 10g  "${vgname}"
 | 
						||
		[ ! -b /dev/mapper/"${vgname}"-usr  ] && lvcreate -n usr  -L 15g  "${vgname}"
 | 
						||
		[ ! -b /dev/mapper/"${vgname}"-var  ] && lvcreate -n var  -L 10g  "${vgname}"
 | 
						||
	fi
 | 
						||
	### Create extra LVs
 | 
						||
	if [ "${manage_extra_lv}" -eq 0 ]; then
 | 
						||
		[ ! -b /dev/mapper/"${vgname}"-vz   ] && lvcreate -n vz   -L 150g "${vgname}"
 | 
						||
		[ ! -b /dev/mapper/"${vgname}"-bkp  ] && lvcreate -n bkp  -L 150g "${vgname}"
 | 
						||
	fi
 | 
						||
	[ ! -b /dev/mapper/"${vgname}"-swap ] && lvcreate -n swap -L 4g   "${vgname}"
 | 
						||
	## }}}
 | 
						||
	## Format Logical Volumes {{{
 | 
						||
	### Format LVs in ext4
 | 
						||
	cd -- /dev/"${vgname}" || exit 1
 | 
						||
	for lvname in *; do
 | 
						||
		mkfs.ext4 -F -L "${lvname}" -- "${lvname}" || exit 4
 | 
						||
	done
 | 
						||
	cd -- - || exit 1
 | 
						||
 | 
						||
	### (re)format Btrfs LV
 | 
						||
	if [ "${manage_btrfs}" -eq 0 ]; then
 | 
						||
		### Ensure to format Btrfs LV
 | 
						||
		mkfs.btrfs --force -L root -- /dev/"${vgname}"/root || exit 4
 | 
						||
	fi
 | 
						||
 | 
						||
	### And format the swap
 | 
						||
	mkswap -L sw01 -- /dev/mapper/"${vgname}"-swap || exit 4
 | 
						||
	## }}}
 | 
						||
fi
 | 
						||
 | 
						||
# }}}
 | 
						||
# Debootstrap {{{
 | 
						||
## Create and mount the system {{{
 | 
						||
### Root
 | 
						||
mkdir -p -- /target
 | 
						||
mountpoint -q /target            || mount -- /dev/mapper/"${vgname}"-root /target
 | 
						||
 | 
						||
if [ "${manage_grub}" -eq 0 ]; then
 | 
						||
	### boot - grub
 | 
						||
	mkdir -p -- /target/boot
 | 
						||
	mountpoint -q /target/boot       || mount -- ${hdd}1 /target/boot
 | 
						||
	boot_uuid=$(blkid | grep "${hdd}1" | sed 's/.*1.*UUID="\(.*\)" TYPE.*/\1/')
 | 
						||
	### Prepare an fstab file
 | 
						||
	printf '%b\n' "UUID=${boot_uuid}               /boot       ext3 defaults                   0 0" > /tmp/target.fstab
 | 
						||
fi
 | 
						||
 | 
						||
### Prepare the base system tree according to the expected file system
 | 
						||
if [ "${manage_btrfs}" -eq 0 ]; then
 | 
						||
	#### Download an extra script for Btrfs
 | 
						||
	wget -O /tmp/part.btrfs.sh "https://git.101010.fr/gardouille-dotfiles/scripts/raw/master/debian/part.btrfs.sh"
 | 
						||
	#### Create several subvolumes
 | 
						||
	chmod +x /tmp/part.btrfs.sh && /tmp/part.btrfs.sh
 | 
						||
 | 
						||
	#### root
 | 
						||
	grep "btrfs" /etc/mtab >> /tmp/target.fstab
 | 
						||
 | 
						||
else  ### Or for ext4, create mountpoint and mount LV
 | 
						||
	#### root
 | 
						||
	printf '%b\n' "/dev/mapper/${vgname}-root /           ext4 defaults                   0 0" >> /tmp/target.fstab
 | 
						||
	#### home LV
 | 
						||
	mkdir -p -- /target/home
 | 
						||
	mountpoint -q /target/home       || mount -- /dev/mapper/"${vgname}"-home /target/home
 | 
						||
	printf '%b\n' "/dev/mapper/${vgname}-home /home       ext4 defaults                   0 0" >> /tmp/target.fstab
 | 
						||
	#### opt LV
 | 
						||
	mkdir -p -- /target/opt
 | 
						||
	mountpoint -q /target/opt        || mount -- /dev/mapper/"${vgname}"-opt /target/opt
 | 
						||
	printf '%b\n' "/dev/mapper/${vgname}-opt  /opt        ext4 defaults                   0 0" >> /tmp/target.fstab
 | 
						||
	#### srv LV
 | 
						||
	mkdir -p -- /target/srv
 | 
						||
	mountpoint -q /target/srv        || mount -- /dev/mapper/"${vgname}"-srv /target/srv
 | 
						||
	printf '%b\n' "/dev/mapper/${vgname}-srv  /srv        ext4 defaults                   0 0" >> /tmp/target.fstab
 | 
						||
	#### tmp LV
 | 
						||
	mkdir -p -- /target/tmp
 | 
						||
	chmod 0777 -- /target/tmp
 | 
						||
	mountpoint -q /target/tmp        || mount -- /dev/mapper/"${vgname}"-tmp /target/tmp
 | 
						||
	printf '%b\n' "/dev/mapper/${vgname}-tmp  /tmp        ext4 defaults                   0 0" >> /tmp/target.fstab
 | 
						||
	#### usr LV
 | 
						||
	mkdir -p -- /target/usr
 | 
						||
	mountpoint -q /target/usr        || mount -- /dev/mapper/"${vgname}"-usr /target/usr
 | 
						||
	printf '%b\n' "/dev/mapper/${vgname}-usr  /usr        ext4 defaults                   0 0" >> /tmp/target.fstab
 | 
						||
	#### var LV
 | 
						||
	mkdir -p -- /target/var
 | 
						||
	mountpoint -q /target/var        || mount -- /dev/mapper/"${vgname}"-var /target/var
 | 
						||
	printf '%b\n' "/dev/mapper/${vgname}-var  /var        ext4 defaults                   0 0" >> /tmp/target.fstab
 | 
						||
fi
 | 
						||
 | 
						||
### Ensure to remove any occurence to /target mountpoint
 | 
						||
sed -i 's;target/;;' /tmp/target.fstab
 | 
						||
sed -i 's;target;;' /tmp/target.fstab
 | 
						||
 | 
						||
if [ "${manage_extra_lv}" -eq 0 ]; then
 | 
						||
	### Extra bkp LV
 | 
						||
	mkdir -p -- /target/srv/backup
 | 
						||
	mountpoint -q /target/srv/backup || mount -- /dev/mapper/"${vgname}"-bkp /target/srv/backup
 | 
						||
	printf '%b\n' "/dev/mapper/${vgname}-bkp  /srv/backup ext4 defaults                   0 0" >> /tmp/target.fstab
 | 
						||
	### Extra vz LV
 | 
						||
	mkdir -p -- /target/var/lib/vz
 | 
						||
	mountpoint -q /target/var/lib/vz || mount -- /dev/mapper/"${vgname}"-vz /target/var/lib/vz
 | 
						||
	printf '%b\n' "/dev/mapper/${vgname}-vz   /var/lib/vz ext4 defaults                   0 0" >> /tmp/target.fstab
 | 
						||
fi
 | 
						||
 | 
						||
### Swap
 | 
						||
swapon -- /dev/mapper/"${vgname}"-swap
 | 
						||
## }}}
 | 
						||
## Run debootstrap
 | 
						||
debootstrap --arch amd64 --include="${dbs_pkg_include}" --exclude="${dbs_pkg_exclude}" "${debian_version}" /target http://ftp.fr.debian.org/debian || exit 1
 | 
						||
 | 
						||
# }}}
 | 
						||
# Configure system {{{
 | 
						||
## Fstab {{{
 | 
						||
### Copy the temp fstab file to target
 | 
						||
cp -- /tmp/target.fstab /target/etc/fstab
 | 
						||
## }}}
 | 
						||
## Ensure to (re)mount devices for chroot {{{
 | 
						||
mkdir -p --   /target/dev
 | 
						||
mountpoint -q /target/dev        || mount -t devtmpfs -- none      /target/dev
 | 
						||
mkdir -p --   /target/dev/pts
 | 
						||
mountpoint -q /target/dev/pts    || mount -t devpts   -- /dev/pts  /target/dev/pts
 | 
						||
mkdir -p --   /target/proc
 | 
						||
mountpoint -q /target/proc       || mount -t proc     -- none      /target/proc
 | 
						||
mkdir -p --   /target/sys
 | 
						||
mountpoint -q /target/sys        || mount -t sysfs    -- none      /target/sys
 | 
						||
### FIXME : /run/lvm needs to be manually set in debootstrap|chroot for Buster {{{
 | 
						||
### See :
 | 
						||
### https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=918590
 | 
						||
### https://bbs.archlinux.org/viewtopic.php?pid=1820949#p1820949
 | 
						||
mkdir -p --   /target/run/lvm
 | 
						||
mountpoint -q /target/run/lvm    || mount --bind      -- /run/lvm  /target/run/lvm
 | 
						||
mkdir -p --   /target/run/udev
 | 
						||
mountpoint -q /target/run/udev   || mount --bind      -- /run/udev /target/run/udev
 | 
						||
### }}}
 | 
						||
## }}}
 | 
						||
## Luks {{{
 | 
						||
if [ "${manage_luks}" -eq 0 ]; then
 | 
						||
	luks_part_uuid=$(blkid | grep "${hdd}2.*TYPE=\"crypto_LUKS\"" | sed 's/.*UUID="\(.*\)" TYPE.*/\1/')
 | 
						||
	### Ensure crypttab file contains the LUKS informations
 | 
						||
	printf '%b\n' "${luks_pv_name} UUID=${luks_part_uuid} none luks,discard" >> /target/etc/crypttab
 | 
						||
fi
 | 
						||
 | 
						||
### Regenerate initramfs
 | 
						||
chroot /target update-initramfs -k all -u
 | 
						||
## }}}
 | 
						||
## Network {{{
 | 
						||
### Get all informations from current network configuration in rescue mode
 | 
						||
net_device=$(ip r | grep "^default" | head -1 | cut -d" " -f5)
 | 
						||
#### TODO: Switch to ip a to get ip address
 | 
						||
net_address=$(ip r | grep -vE "(^default|metric)" | grep "${net_device}.*src" | head -1 | awk -F" " '{print $NF}')
 | 
						||
read -r net_mac_address </sys/class/net/"${net_device}"/address
 | 
						||
net_netmask=$(ipcalc "${net_address}" | awk '/Netmask:/{print $2;}')
 | 
						||
net_netmask_cidr=$(ipcalc "${net_address}" | awk '/Netmask:/{print $4;}')
 | 
						||
net_broadcast=$(ip a s dev "${net_device}" | awk '/inet.*brd/{print $4}')
 | 
						||
net_network=$(ip r | grep -vE "(^default|metric)" | grep "src ${net_address}" | head -1 | cut -d"/" -f1)
 | 
						||
net_gateway=$(ip r | grep "^default" | head -1 | cut -d" " -f3)
 | 
						||
 | 
						||
### Create a network unit for systemd-networkd
 | 
						||
printf '%b' "[Match]
 | 
						||
MACAddress=${net_mac_address}
 | 
						||
 | 
						||
[Network]
 | 
						||
Description=network interface with default route without dhcp
 | 
						||
DHCP=no
 | 
						||
Address=${net_address}/${net_netmask_cidr}
 | 
						||
Gateway=${net_gateway}
 | 
						||
IPv6AcceptRA=no
 | 
						||
DNS=80.67.169.12
 | 
						||
" > /target/etc/systemd/network/50-default.network
 | 
						||
 | 
						||
### Ensure to enable systemd-networkd at startup
 | 
						||
chroot /target systemctl enable systemd-networkd
 | 
						||
 | 
						||
## }}}
 | 
						||
## Locale {{{
 | 
						||
### Enable locale(s)
 | 
						||
sed -i 's/^# \(en_US.UTF-8 UTF-8\)/\1/' /target/etc/locale.gen
 | 
						||
#sed -i 's/^# \(fr_FR.UTF-8 UTF-8\)/\1/' /target/etc/locale.gen
 | 
						||
chroot /target locale-gen
 | 
						||
 | 
						||
## }}}
 | 
						||
## Timezone {{{
 | 
						||
### Set timezone
 | 
						||
printf '%b\n' "Europe/Paris" > /target/etc/timezone
 | 
						||
ln -fs /usr/share/zoneinfo/Europe/Paris /target/etc/localtime
 | 
						||
chroot /target dpkg-reconfigure --frontend noninteractive tzdata
 | 
						||
 | 
						||
## }}}
 | 
						||
## Kernel and Grub {{{
 | 
						||
### Install
 | 
						||
if [ "${manage_grub}" -eq 0 ]; then
 | 
						||
	chroot /target aptitude install --assume-yes --without-recommends -- linux-image-amd64 grub-pc
 | 
						||
	chroot /target grub-install "${hdd}"
 | 
						||
	chroot /target update-grub
 | 
						||
else
 | 
						||
	chroot /target aptitude install --assume-yes --without-recommends -- linux-image-amd64
 | 
						||
fi
 | 
						||
## }}}
 | 
						||
## Hostname {{{
 | 
						||
 | 
						||
if [ -z "${new_hostname}" ]; then
 | 
						||
	lookup_hostname=$(nslookup "${net_address}" || echo "server name = new_server")
 | 
						||
	get_hostname=$(echo "${lookup_hostname}" | awk '/name =/{print $4;}' | cut -d. -f1)
 | 
						||
	printf '%b\n' "${get_hostname}" > /target/etc/hostname
 | 
						||
else
 | 
						||
	printf '%b\n' "${new_hostname}" > /target/etc/hostname
 | 
						||
fi
 | 
						||
#printf '%b\n' "127.0.0.1       ${new_hostname}" >> /target/etc/hosts
 | 
						||
 | 
						||
## }}}
 | 
						||
# }}}
 | 
						||
# Finish {{{
 | 
						||
## Call a latecommand script {{{
 | 
						||
wget -O /tmp/latecommand.tar.gz "https://git.ipr.univ-rennes1.fr/cellinfo/tftpboot/raw/master/scripts/latecommand.tar.gz" --no-check-certificate
 | 
						||
tar xzf /tmp/latecommand.tar.gz -C /target/tmp/
 | 
						||
chroot /target /usr/bin/env debian_version="${debian_version}" /bin/sh /tmp/latecommand/post."${debian_version}".sh
 | 
						||
 | 
						||
## }}}
 | 
						||
## SSH {{{
 | 
						||
### Allow root connections - this should be fixed if it works
 | 
						||
sed -i 's/\(^\|^\#\)\(PermitRootLogin\).*/\2 yes/g' /target/etc/ssh/sshd_config
 | 
						||
### Add current authorized_keys from the rescue system if present
 | 
						||
if [ -f /root/.ssh/authorized_keys ]; then
 | 
						||
	mkdir -p -- /target/root/.ssh
 | 
						||
	cp -- /root/.ssh/authorized_keys /target/root/.ssh/authorized_keys
 | 
						||
else
 | 
						||
	printf '%b\n' "${REDB}You might want to define an authorized key for SSH/root in /target/etc/ssh/sshd_config${RESET}"
 | 
						||
fi
 | 
						||
## }}}
 | 
						||
printf '%b\n' "${REDB}Please change the root's password :${RESET}"
 | 
						||
chroot /target passwd
 | 
						||
 | 
						||
# Ensure to umount everything
 | 
						||
#umount /target/var/lib/vz/ /target/var/ /target/usr/ /target/tmp/ /target/sys/ /target/srv/backup/ /target/srv/ /target/proc/ /target/opt/ /target/home/ /target/dev/pts/ /target/dev /target/boot/ /target/
 | 
						||
 | 
						||
printf '%b\n' "${GREEN}The system is still available on /target but you can now try to reboot the hardware.${RESET}"
 | 
						||
 | 
						||
exit 0
 | 
						||
# }}}
 |