2023-04-24 10:11:09 +00:00
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
|
|
# Ce script est une base qu’il faut sûrement améliorer.
|
|
|
|
|
# Il sert à installer un debian d’ordi portable JC pour le cluster SHLAGO
|
|
|
|
|
# Le but est d’installer juste ce qu’il faut pour le le serveur tourne, le reste est laissé à ansible.
|
|
|
|
|
# Il génère une clé SSH qui permettra d’accéder à la machine. C’est peut-être con, il faudrait plutôt le remplir de nos ssh publiques.
|
|
|
|
|
|
|
|
|
|
# https://github.com/adrianamaglio/driglibash
|
|
|
|
|
declare -A usage
|
|
|
|
|
declare -A varia
|
2023-08-02 09:36:53 +00:00
|
|
|
|
export driglibash_run_retry=true
|
2023-04-24 10:11:09 +00:00
|
|
|
|
version="alpha nightly 0.0.1 pre-release unstable"
|
|
|
|
|
summary="$0 [options]"
|
|
|
|
|
|
|
|
|
|
usage[m]="Path of the temporar mount point"
|
|
|
|
|
varia[m]=mnt
|
|
|
|
|
mnt="temporary_mount_point"
|
|
|
|
|
|
|
|
|
|
usage[a]="The architecture of installed system as supported by debootstrap"
|
|
|
|
|
varia[a]=arch
|
|
|
|
|
arch="amd64"
|
|
|
|
|
|
|
|
|
|
usage[r]="The release of installed system as supported by debootstrap"
|
|
|
|
|
varia[r]=release
|
|
|
|
|
release="bullseye"
|
|
|
|
|
|
|
|
|
|
usage[s]="Source repository of installed system"
|
|
|
|
|
varia[s]=repo
|
|
|
|
|
#repo=
|
|
|
|
|
repo="http://ftp.fr.debian.org/debian"
|
|
|
|
|
#repo="http://localhost:3142/ftp.fr.debian.org/debian"
|
|
|
|
|
|
2023-05-18 08:03:11 +00:00
|
|
|
|
usage[S]="Additional sources to add in source.list. Newline separated."
|
|
|
|
|
varia[S]=repos
|
|
|
|
|
repos="deb http://ftp.fr.debian.org/debian stable main contrib non-free"
|
|
|
|
|
|
2023-04-24 10:11:09 +00:00
|
|
|
|
usage[n]="The hostname"
|
|
|
|
|
varia[n]=hostname
|
|
|
|
|
hostname=""
|
|
|
|
|
|
|
|
|
|
usage[b]="The device where grub will be installed"
|
|
|
|
|
varia[b]=boot_device
|
|
|
|
|
boot_device=
|
|
|
|
|
|
2023-08-02 09:36:53 +00:00
|
|
|
|
usage[B]="Boot partition"
|
|
|
|
|
varia[B]=boot_part
|
|
|
|
|
boot_part=
|
|
|
|
|
|
2023-04-24 10:11:09 +00:00
|
|
|
|
usage[R]="The device where the system will be installed"
|
2023-05-16 19:25:16 +00:00
|
|
|
|
varia[R]=root_device
|
|
|
|
|
root_device=
|
2023-04-24 10:11:09 +00:00
|
|
|
|
|
|
|
|
|
usage[l]="System locale"
|
|
|
|
|
varia[l]=locale
|
|
|
|
|
locale="en_US.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8"
|
|
|
|
|
|
2023-05-16 19:25:16 +00:00
|
|
|
|
usage[w]="Wireguard IP last number (4 for 1.2.3.4)"
|
|
|
|
|
varia[w]=wireguard_number
|
|
|
|
|
wireguard_number=
|
|
|
|
|
|
2023-05-18 08:03:11 +00:00
|
|
|
|
usage[J]="Just mount and chroot it. No installation"
|
|
|
|
|
varia[J]=just_mount
|
|
|
|
|
just_mount=false
|
|
|
|
|
|
|
|
|
|
usage[i]="Packages to install. space separated"
|
|
|
|
|
varia[i]=install
|
|
|
|
|
install=
|
2023-05-16 19:25:16 +00:00
|
|
|
|
|
2023-08-02 09:36:53 +00:00
|
|
|
|
usage[u]="Install grub as UEFI (not working)"
|
|
|
|
|
varia[u]=uefi
|
|
|
|
|
uefi=false
|
|
|
|
|
|
|
|
|
|
usage[I]="Interractive mode. Ask questions if needed."
|
|
|
|
|
varia[I]=interractive
|
|
|
|
|
interractive=false
|
|
|
|
|
|
2023-08-28 18:25:32 +00:00
|
|
|
|
usage[D]="Data Device. Will be encrypted."
|
|
|
|
|
varia[D]=data_device
|
|
|
|
|
data_device=
|
2023-04-24 10:11:09 +00:00
|
|
|
|
|
|
|
|
|
. driglibash-args
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
secret_dir=secrets
|
|
|
|
|
secret_dir="$(realpath -m "$secret_dir/$hostname")"
|
2023-08-02 09:36:53 +00:00
|
|
|
|
install="$install linux-image-amd64 console-data grub2 locales vim openssh-server git nginx smartmontools tcpdump netcat-openbsd wireguard"
|
2023-04-24 10:11:09 +00:00
|
|
|
|
|
2023-05-18 08:03:11 +00:00
|
|
|
|
debootstrap_done_marker="$mnt/etc/debootstrap_done"
|
2023-08-02 09:36:53 +00:00
|
|
|
|
uefi_mountpoint=/boot/efi
|
2023-04-24 10:11:09 +00:00
|
|
|
|
|
2024-04-18 14:22:32 +00:00
|
|
|
|
dependancies="cryptsetup locales openssh-server wireguard-tools grub2"
|
2023-04-24 10:11:09 +00:00
|
|
|
|
###############################################################################
|
|
|
|
|
# Actual script
|
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
chroot_run(){
|
2023-08-02 09:36:53 +00:00
|
|
|
|
run chroot "$mnt" $@
|
2023-05-18 08:03:11 +00:00
|
|
|
|
if [ "$?" -ne 0 ] && [ "$?" != '0' ] ; then
|
2023-04-24 10:11:09 +00:00
|
|
|
|
die "Error, chroot command [$@] exited with code '$?'"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wait_for_user(){
|
|
|
|
|
section "Time for a pause"
|
|
|
|
|
run echo "Press 'Enter' to continue"
|
|
|
|
|
read
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mount_misc(){
|
|
|
|
|
run mkdir -p "$mnt"/{proc,dev,sys}
|
2023-05-16 19:25:16 +00:00
|
|
|
|
run mount -t proc /proc "$mnt/proc"
|
|
|
|
|
#clean "umount '$(realpath "$mnt/proc")'"
|
2023-04-24 10:11:09 +00:00
|
|
|
|
# To access physical devices
|
2023-05-16 19:25:16 +00:00
|
|
|
|
run mount --rbind --make-rslave /dev "$mnt/dev"
|
2023-05-18 08:03:11 +00:00
|
|
|
|
# even explicitly mounting /dev/pts makes apt cry for its absence…
|
2023-05-16 19:25:16 +00:00
|
|
|
|
#clean "umount -R '$(realpath "$mnt/dev")'"
|
|
|
|
|
run mount --rbind --make-rslave /sys "$mnt/sys"
|
|
|
|
|
#clean "umount -R '$(realpath "$mnt/sys")'"
|
2023-08-02 09:36:53 +00:00
|
|
|
|
if "$uefi" ; then
|
|
|
|
|
run mkdir -p "$mnt$uefi_mountpoint"
|
|
|
|
|
run mount "$boot_device" "$mnt$uefi_mountpoint"
|
|
|
|
|
fi
|
2023-05-16 19:25:16 +00:00
|
|
|
|
clean "umount -R '$mnt'"
|
2023-04-24 10:11:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if [ -z "$hostname" ] ; then
|
|
|
|
|
die "Hostname arg needed"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
root_or_die
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
section "Testing for existing secrets"
|
|
|
|
|
if ! [ -d "$secret_dir" ] ; then
|
|
|
|
|
run mkdir -p "$secret_dir"
|
|
|
|
|
run chown -R root:root "$secret_dir"
|
|
|
|
|
run chmod 700 "$secret_dir"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
2023-05-16 19:25:16 +00:00
|
|
|
|
section "Mounting additionnal items"
|
|
|
|
|
if [ -n "$(df | grep "$root_device")" ] ; then
|
|
|
|
|
run umount "$root_device"
|
|
|
|
|
fi
|
2023-05-18 08:03:11 +00:00
|
|
|
|
run mkdir -p "$mnt"
|
2023-05-16 19:25:16 +00:00
|
|
|
|
run mount --make-private "$root_device" "$mnt"
|
2023-08-02 09:36:53 +00:00
|
|
|
|
# bug in driglibash-base. If $mnt got spaces it breaks
|
|
|
|
|
if [ -n "$boot_part" ] ; then
|
|
|
|
|
run mkdir -p "$mnt/boot"
|
|
|
|
|
run mount "$boot_part" "$mnt/boot"
|
|
|
|
|
fi
|
2023-05-18 08:03:11 +00:00
|
|
|
|
clean "umount -R $mnt"
|
2023-05-16 19:25:16 +00:00
|
|
|
|
|
|
|
|
|
|
2023-05-18 08:03:11 +00:00
|
|
|
|
if [ "$just_mount" != false ] ; then
|
|
|
|
|
echo 'Mounted. Exit shell to unmount.'
|
|
|
|
|
chroot_run
|
|
|
|
|
die 'You asked to just mount then exit.'
|
2023-05-16 19:25:16 +00:00
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
section "debootstraping"
|
2023-05-18 08:03:11 +00:00
|
|
|
|
if [ ! -f "$debootstrap_done_marker" ] ; then
|
|
|
|
|
# Debootstrap may fail when the target is an existing system
|
2023-08-02 09:36:53 +00:00
|
|
|
|
if [ -n "$(ls -A $mnt | grep -vi -e 'lost+found' -e boot)" ]; then
|
|
|
|
|
yell "Root dir '$mnt' is not empty."
|
|
|
|
|
if "$interractive" ; then
|
|
|
|
|
read -p 'Press enter to continue anyway'
|
|
|
|
|
else
|
|
|
|
|
die "Won’t debootstrap it. Is this installation broken?"
|
|
|
|
|
fi
|
2023-05-18 08:03:11 +00:00
|
|
|
|
fi
|
|
|
|
|
run debootstrap --verbose --arch "$arch" "$release" "$mnt" "$repo"
|
|
|
|
|
touch "$debootstrap_done_marker"
|
|
|
|
|
else
|
|
|
|
|
yell "Already done"
|
|
|
|
|
fi
|
2023-04-24 10:11:09 +00:00
|
|
|
|
|
|
|
|
|
mount_misc
|
|
|
|
|
|
|
|
|
|
section "Installing selected software"
|
2023-05-18 08:03:11 +00:00
|
|
|
|
echo "$repos" >> "$mnt/etc/apt/sources.list"
|
2023-08-02 09:36:53 +00:00
|
|
|
|
run chroot "$mnt" <<EOF
|
2023-04-24 10:11:09 +00:00
|
|
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
|
|
|
apt-get update -q -y
|
2024-04-18 14:22:32 +00:00
|
|
|
|
apt-get install -q -y $install
|
2023-04-24 10:11:09 +00:00
|
|
|
|
EOF
|
|
|
|
|
# TODO watershed ?
|
|
|
|
|
|
|
|
|
|
|
2023-08-02 09:36:53 +00:00
|
|
|
|
section "Generating locales"
|
|
|
|
|
echo -e "$locale" > "$mnt/etc/locale.gen"
|
|
|
|
|
chroot_run locale-gen
|
|
|
|
|
|
2023-04-24 10:11:09 +00:00
|
|
|
|
|
2023-08-28 18:25:32 +00:00
|
|
|
|
if [ -n "$data_device" ] ; then
|
2023-09-13 08:46:02 +00:00
|
|
|
|
section "Mounting and encrypting data dir"
|
|
|
|
|
run cryptsetup create --type plain dmcrypt-jeancloud "$data_device"
|
|
|
|
|
run mkfs.ext4 dmcrypt-jeancloud
|
|
|
|
|
uuid="$(blkid | grep dmcrypt-jeancloud | grep -o 'UUID="[^"]\+"')"
|
|
|
|
|
if [ -z "$uuid" ] ; then
|
|
|
|
|
die "Error, unexpected empty uuid"
|
|
|
|
|
fi
|
|
|
|
|
line_in_file "$uuid /data ext4 rw,nofail 0 1" "$mnt/etc/fstab"
|
2023-08-28 18:25:32 +00:00
|
|
|
|
fi
|
|
|
|
|
|
2023-04-24 10:11:09 +00:00
|
|
|
|
|
|
|
|
|
section "Configuring new system"
|
|
|
|
|
uuid=$(blkid | grep "$root_device" | cut -d ' ' -f 2)
|
|
|
|
|
line_in_file "$uuid / ext4 errors=remount-ro 0 1" "$mnt/etc/fstab"
|
|
|
|
|
line_in_file "proc /proc proc defaults" "$mnt/etc/fstab"
|
|
|
|
|
# TODO set noauto to /boot if needed
|
|
|
|
|
|
|
|
|
|
# Set hostname
|
|
|
|
|
run echo "$hostname" > "$mnt/etc/hostname"
|
|
|
|
|
|
2023-08-28 18:25:32 +00:00
|
|
|
|
# Prenvent suspend on lid close
|
2023-09-13 08:46:02 +00:00
|
|
|
|
line_in_file HandleLidSwitch=ignore "$mnt/etc/systemd/logind.conf"
|
|
|
|
|
|
|
|
|
|
# Inform futur scripts that /data is not mounted
|
|
|
|
|
touch "$mnt/data/mounted"
|
2023-08-28 18:25:32 +00:00
|
|
|
|
|
2023-09-13 08:46:02 +00:00
|
|
|
|
# Fix path
|
2023-04-24 10:11:09 +00:00
|
|
|
|
run cat > "$mnt/root/.bashrc" <<EOF
|
|
|
|
|
PATH=$PATH:/usr/bin:/bin:/sbin:/usr/sbin:/sbin
|
2023-09-13 08:46:02 +00:00
|
|
|
|
setterm -powerdown 0
|
2023-04-24 10:11:09 +00:00
|
|
|
|
EOF
|
|
|
|
|
# Be sure this fucking beep is gone
|
|
|
|
|
echo 'set bell-style none' >> "$mnt/etc/inputrc"
|
2023-09-13 08:46:02 +00:00
|
|
|
|
# TODO find a second method to kill this doomed beep
|
|
|
|
|
line_in_file '@reboot root shutdownscreen.sh' "$mnt/etc/crontab"
|
2023-04-24 10:11:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# boot crypted
|
|
|
|
|
#section "Installing cryptsetup in initramfs"
|
|
|
|
|
#run echo 'CRYPTSETUP=y' >> /etc/cryptsetup-initramfs/conf-hook
|
|
|
|
|
#run cp key "$mnt/root/"
|
|
|
|
|
#run echo 'FILES="/root/key"' >> /etc/initramfs-tools/initramfs.conf
|
|
|
|
|
#run update-initramfs -ut
|
|
|
|
|
#echo "$mnt/etc/initramfs-tools/conf.d/cryptsetup" <<EOF
|
|
|
|
|
## This will setup non-us keyboards in early userspace,
|
|
|
|
|
## necessary for punching in passphrases.
|
|
|
|
|
#KEYMAP=y
|
|
|
|
|
#
|
|
|
|
|
## force busybox and cryptsetup on initramfs
|
|
|
|
|
#BUSYBOX=y
|
|
|
|
|
#CRYPTSETUP=y
|
|
|
|
|
#
|
|
|
|
|
## and for systems using plymouth instead, use the new option
|
|
|
|
|
#FRAMEBUFFER=y
|
|
|
|
|
#EOF
|
|
|
|
|
#echo 'export CRYPTSETUP=y' >> "$mnt/etc/environment"
|
|
|
|
|
#echo 'export FILES="./key"' >> "$mnt/etc/initramfs-tools/initramfs.conf"
|
|
|
|
|
#chroot_run 'update-initramfs -ut'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
section "Set up networking"
|
|
|
|
|
# Disable the unpredictable naming (since we are not on the future host)
|
2023-08-02 09:36:53 +00:00
|
|
|
|
if [ ! -L "$mnt/etc/udev/rules.d/80-net-setup-link.rules" ] ; then
|
|
|
|
|
run ln -s /dev/null "$mnt/etc/udev/rules.d/80-net-setup-link.rules"
|
|
|
|
|
fi
|
2023-04-24 10:11:09 +00:00
|
|
|
|
run cat >> "$mnt/etc/network/interfaces" <<EOF
|
|
|
|
|
allow-hotplug eth0
|
|
|
|
|
iface eth0 inet dhcp
|
|
|
|
|
EOF
|
2023-05-18 08:03:11 +00:00
|
|
|
|
#iface eth0 inet6 dhcp
|
2023-04-24 10:11:09 +00:00
|
|
|
|
# TODO add dyndn service
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
section "Creating root SSH key to connect"
|
|
|
|
|
if [ -n "$(ls -A $secret_dir)" ]; then
|
|
|
|
|
#die "Secret dir '$secret_dir' is not empty"
|
2023-05-16 19:25:16 +00:00
|
|
|
|
yell "Secret dir is not empty. May erase key."
|
2023-04-24 10:11:09 +00:00
|
|
|
|
fi
|
2023-08-28 18:25:32 +00:00
|
|
|
|
run export HOSTNAME="$hostname" && ssh-keygen -b 4096 -f "$secret_dir/id_rsa" -P '' -C "access@$hostname"
|
2023-05-16 19:25:16 +00:00
|
|
|
|
run mkdir -p "$mnt/root/.ssh/"
|
|
|
|
|
cat "$secret_dir/id_rsa.pub" >> "$mnt/root/.ssh/authorized_keys"
|
2023-05-18 08:03:11 +00:00
|
|
|
|
chroot_run systemctl enable ssh
|
2023-05-16 19:25:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
section "Creating wireguard conf"
|
2023-05-18 08:03:11 +00:00
|
|
|
|
|
2023-05-16 19:25:16 +00:00
|
|
|
|
if [ -n "$wireguard_number" ] ; then
|
|
|
|
|
run cat >> "$mnt/etc/wireguard/jeancloud.conf" <<EOF
|
|
|
|
|
[Interface]
|
2024-06-20 08:15:44 +00:00
|
|
|
|
PrivateKey = $(chroot_run wg genkey)
|
2023-05-16 19:25:16 +00:00
|
|
|
|
ListenPort = 51812
|
|
|
|
|
Address = 10.98.1.$wireguard_number/32
|
|
|
|
|
|
|
|
|
|
[Peer] # debug
|
|
|
|
|
PublicKey = OpENQI1ElPuVdNssMySffO8iZEyJsOaSQ9bQLU6Uz2E=
|
|
|
|
|
AllowedIPs = 10.98.1.254/32
|
|
|
|
|
Endpoint = 193.33.56.94:51812
|
|
|
|
|
PersistentKeepalive = 25
|
|
|
|
|
EOF
|
2024-06-20 08:15:44 +00:00
|
|
|
|
wireguard_pubkey="$(cat "$mnt/etc/wireguard/jeancloud.conf" | grep -oP '^PrivateKey = \K.*' | chroot_run wg pubkey)"
|
2023-05-16 19:25:16 +00:00
|
|
|
|
|
2023-08-02 09:36:53 +00:00
|
|
|
|
run cat > "$secret_dir/wg_conf_part" <<EOF
|
2023-05-16 19:25:16 +00:00
|
|
|
|
[Peer] # $hostname
|
|
|
|
|
PublicKey = $wireguard_pubkey
|
|
|
|
|
AllowedIPs = 10.98.1.$wireguard_number/32
|
|
|
|
|
EOF
|
2023-05-18 08:03:11 +00:00
|
|
|
|
chroot_run systemctl enable wg-quick@jeancloud.service
|
2023-04-24 10:11:09 +00:00
|
|
|
|
|
2023-05-16 19:25:16 +00:00
|
|
|
|
else
|
|
|
|
|
yell "Passing"
|
|
|
|
|
fi
|
2023-04-24 10:11:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
section "Installing grub"
|
2023-08-02 09:36:53 +00:00
|
|
|
|
# Disable predictable interfaces name since we are not on the target host
|
2023-04-24 10:11:09 +00:00
|
|
|
|
run sed -i 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"/g' "$mnt/etc/default/grub"
|
|
|
|
|
chroot_run update-grub
|
2023-08-02 09:36:53 +00:00
|
|
|
|
if $uefi ; then
|
|
|
|
|
chroot_run grub-install --efi-directory="$uefi_mountpoint" --recheck "$boot_device"
|
|
|
|
|
else
|
|
|
|
|
chroot_run grub-install --recheck "$boot_device"
|
|
|
|
|
fi
|
2023-04-24 10:11:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if [ "$arg_test" != "false" ] ; then
|
|
|
|
|
section "Testing installed system"
|
|
|
|
|
run qemu-system-x86_64 -m 1024M "$boot_device"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "To test the system with qemu type:"
|
|
|
|
|
echo "qemu-system-x86_64 -m 1024M '$boot_device'"
|
|
|
|
|
|
|
|
|
|
clean
|