| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 | 
							- #!/bin/bash -e
 
- #----------
 
- # Interactive installation steps for Debian Bullseye from GRML using debootstrap
 
- # Design decisions
 
- # - Fokus on a simple setup, primarly for VMs
 
- # - One disk, one partion, swap-file in the same partion as safety net
 
- # - Use systemd whereever possible (network, ntp, cron, journald logging)
 
- # - Minimal number of packages & cloud kernel
 
- # - grub-pc, not efi
 
- # - random root and admin user password generation
 
- # - ssh on port 50101 limited to the admin user
 
- # Usage
 
- # # Boot grml
 
- # passwd root
 
- # grml-network
 
- # Start ssh
 
- # git clone https://git.in-ulm.de/ulpeters/bootstrap.git
 
- # cp config.sh.template config.sh                    # copy template
 
- # config-get-netconf-eth0.sh                         # get running grml network config
 
- # vi config.sh                                       # update installation variables
 
- # bootstrap-bullseye.sh install                      # start installation
 
- # !! Note down the admin passwords and reboot
 
- # sudo /installer/bootstrap-bullseye.sh postinstall  # run postinstall in the new system
 
- # Variables
 
- mnt="/mnt/root"  # mountpoint for the new root filesystem
 
- hostname="somehost.example.com"
 
- disk="/dev/vda"  # lsblk --list
 
- disk1=$disk"1"
 
- netDev="eth0"    # ip link
 
- netAddress="203.0.113.66/24"
 
- netGateway="203.0.113.1"
 
- netBroadcast="203.0.113.255"
 
- netDNS1="192.0.2.10"
 
- netDNS2="198.51.100.10"
 
- netNTP="pool.ntp.org"
 
- extraPackages=""
 
- [ -f ./config.sh ] && source config.sh
 
- # Setup network in grml
 
- grmlnetwork(){
 
- ip link show # list interfaces
 
- ip addr add $netAddress dev $netDev
 
- ip link set $netDev up
 
- ip route add default via $netGateway
 
- echo nameserver $netDNS1 >> /etc/resolv.conf
 
- echo nameserver $netDNS2 >> /etc/resolv.conf
 
- }
 
- install(){
 
- #----------
 
- # Prepare disks
 
- # Parition disks -- pkg: parted
 
- parted $disk -s \
 
- mklabel msdos \
 
- mkpart primary ext4 512M 100% toggle 1 boot
 
- fdisk -l $disk
 
- # Format disks -- pkg: e2fsprogs dosfstools and to file system check
 
- mkfs.ext4 $disk1 && e2fsck $disk1
 
- # Prepare mount points and mount
 
- mkdir -p $mnt
 
- mount $disk1 $mnt
 
- # Create swapfile
 
- swapfile=$mnt/swapfile
 
- dd if=/dev/zero of=$swapfile bs=1M count=1024 status=progress # create 1GB  file
 
- chmod 600 $swapfile #restric permissions
 
- mkswap $swapfile #format file
 
- #----------
 
- # Bootstrap -- pkg: debootstrap
 
- # Remark: Debootstrap does not install recommands!! 
 
- debootstrap --variant=minbase --arch=amd64 bookworm $mnt http://ftp2.de.debian.org/debian/
 
- #----------
 
- # Configuration
 
- # Configure disk mounts
 
- # Or get UUID from blkid...
 
- cat >$mnt/etc/fstab <<EOL
 
- $disk1        /                     ext4 rw       0 0
 
- /swapfile        none                  swap defaults 0 0
 
- EOL
 
- # Configure sources.list
 
- cat >$mnt/etc/apt/sources.list <<EOL
 
- deb http://deb.debian.org/debian bookworm main non-free-firmware
 
- # deb-src http://deb.debian.org/debian bookworm main non-free-firmware
 
- deb http://deb.debian.org/debian-security/ bookworm-security main non-free-firmware
 
- # deb-src http://deb.debian.org/debian-security/ bookworm-security main non-free-firmware
 
- deb http://deb.debian.org/debian bookworm-updates main non-free-firmware
 
- # deb-src http://deb.debian.org/debian bookworm-updates main non-free-firmware
 
- EOL
 
- # Configure hostname
 
- echo "127.0.0.1       $hostname" >> $mnt/etc/hosts
 
- echo "$hostname"                  > $mnt/etc/hostname
 
- #----------
 
- # Prepare chroot
 
- mount -o bind /dev $mnt/dev
 
- mount -o bind /dev/pts $mnt/dev/pts
 
- mount -t sysfs /sys $mnt/sys
 
- mount -t proc /proc $mnt/proc
 
- cp /proc/mounts $mnt/etc/mtab
 
- cp /etc/resolv.conf $mnt/etc/resolv.conf
 
- mkdir -p $mnt/installer
 
- cp $(dirname `realpath $0`)/*.sh $mnt/installer
 
- # Run script in chroot
 
- chroot $mnt /bin/bash /installer/bootstrap-bullseye.sh install2
 
- # Install bootloader
 
- $0 bootloader
 
- }
 
- #----------
 
- # Function executed within chroot
 
- install2(){
 
- source /installer/config.sh 
 
- # Install basic system
 
- apt-get update
 
- apt-get install --yes \
 
-   apt-utils dialog msmtp-mta \
 
-   systemd-sysv locales tzdata haveged \
 
-   linux-image-cloud-amd64 grub-pc \
 
-   iproute2 netbase \
 
-   ssh sudo molly-guard  \
 
-   less vim-tiny bash-completion pwgen lsof \
 
-   dnsutils iputils-ping curl \
 
-   $extraPackages
 
- # Upgrade and clean up
 
- apt-get upgrade --yes
 
- apt-get autoremove --yes
 
- apt-get clean --yes
 
- # Setup users and passwords
 
- [ -z $pwdAdmin ] && pwdAdmin=`pwgen --capitalize --numerals --ambiguous 12 1`
 
- useradd admin --create-home --shell /bin/bash
 
- echo "admin:$pwdAdmin" | chpasswd
 
- usermod -a -G sudo admin
 
- echo -e "\e[1;33;4;44mPassword for the user admin: $pwdAdmin\e[0m"
 
- pass=`pwgen --capitalize --numerals --ambiguous 12 1`
 
- [ -z $pwdRoot ] && pwdRoot=`pwgen --capitalize --numerals --ambiguous 12 1`
 
- echo "root:$pwdRoot"   | chpasswd
 
- echo -e "\e[1;33;4;44mPassword for the user root: $pwdRoot\e[0m"
 
- # Harden SSHD
 
- sed -i -e 's/#Port 22/Port 50101/g' /etc/ssh/sshd_config
 
- sed -i -e 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/g' /etc/ssh/sshd_config
 
- # https://infosec.mozilla.org/guidelines/openssh.html
 
- # Allow admin to sudo without password
 
- echo AllowUsers admin >> /etc/ssh/sshd_config
 
- echo "admin ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/admin
 
- ## Configure network using systemd
 
- if [ -z $netAddress ]
 
- then
 
- ## Network OPTION 1 - DHCP
 
- cat >/etc/systemd/network/20-wired.network <<EOL
 
- [Match]
 
- Name=e*
 
- [Network]
 
- DHCP=ipv4
 
- IPv6PrivacyExtensions=false
 
- IPv6AcceptRA=false
 
- NTP=$netNTP
 
- EOL
 
- else
 
- ## Network OPTION 2 - static
 
- cat >/etc/systemd/network/20-wired.network <<EOL
 
- [Match]
 
- Name=$netDev
 
- [Network]
 
- Address=$netAddress
 
- Gateway=$netGateway
 
- Broadcast=$netBroadcast
 
- DNS=$netDNS1
 
- DNS=$netDNS2
 
- LLMNR=no
 
- MulticastDNS=no
 
- NTP=$netNTP
 
- EOL
 
- fi
 
- ## Setup systemd resolver
 
- #apt-get install --yes systemd-resolved
 
- #rm /etc/resolv.conf
 
- #ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
 
- #systemctl enable systemd-networkd
 
- #systemctl enable systemd-resolved
 
- # Limit journald logging to 1 month, 1 GB in total and split files per week
 
- mkdir -p /etc/systemd/journald.conf.d/
 
- cat >/etc/systemd/journald.conf.d/retention.conf <<EOL
 
- MaxRetentionSec=1month
 
- SystemMaxUse=1G
 
- MaxFileSec=1week
 
- EOL
 
- # Show errors in motd
 
- rm /etc/motd   
 
- cat >/etc/update-motd.d/15-boot-errors<<EOL
 
- #!/bin/sh
 
- echo
 
- journalctl --boot --priority=3 --no-pager
 
- EOL
 
- chmod 755 /etc/update-motd.d/15-boot-errors
 
- # Setup keyboard layout
 
- cat >/etc/default/keyboard <<EOL
 
- XKBMODEL="pc105"
 
- XKBLAYOUT="de"
 
- XKBVARIANT="nodeadkeys"
 
- XKBOPTIONS=""
 
- BACKSPACE="guess"
 
- EOL
 
- # Leave chroot
 
- exit
 
- }
 
- bootloader(){
 
- # Install GRUB in /dev/vba
 
- chroot $mnt /bin/bash -c "grub-install $disk && update-grub"
 
- }
 
- unmount(){
 
- # Unmount if mounted
 
- ! mountpoint -q $mnt/proc    || umount $mnt/proc
 
- ! mountpoint -q $mnt/sys     || umount $mnt/sys
 
- ! mountpoint -q $mnt/dev/pts || umount $mnt/dev/pts
 
- ! mountpoint -q $mnt/dev     || umount $mnt/dev
 
- ! mountpoint -q $mnt/root    || umount $mnt/root
 
- ! mountpoint -q $mnt         || umount $mnt
 
- # Delete mount-point if empty and not mounted
 
- [ -z "$(ls -A /mnt/)" ] &&  ! mountpoint -q $mnt  && rm -R $mnt
 
- }
 
- postinstall(){
 
- ####----REBOOT into the new system, so we'll have dbus running
 
- localectl set-locale LANG=de_DE.UTF-8         # Default for LC_* variables not  set. 
 
- localectl set-locale LC_MESSAGES=en_US.UTF-8  # System messages. 
 
- #localectl set-locale LC_RESPONSE=en_US.UTF-8  # How responses (such as Yes and No) appear
 
- update-locale
 
- timedatectl set-timezone Europe/Berlin
 
- }
 
- # Switch to functions...
 
- case $1 in
 
-   grmlnetwork)
 
-     echo Setup network in grml
 
-     grmlnetwork
 
-     ;;
 
-   install)
 
-     echo "Stage 1: Start installation"
 
-     install
 
-     ;;
 
-   install2)
 
-     echo "Stage 2: Start installation in chroot"
 
-     install2
 
-     ;;
 
-   bootloader)
 
-     echo "Stage 3: Install bootloader and unmount chroot"
 
-     bootloader
 
-     unmount
 
-     echo "We're done and can reboot now"
 
-     ;;
 
-   postinstall)
 
-     echo "Stage 4: Start post-installation in live system"
 
-     postinstall
 
-     ;;
 
-   unmount)
 
-     echo "Unmount chroot, e.g. in case installation fails"
 
-     unmount
 
-     ;;
 
-   *)
 
-     echo "Valid functions are: grmlnetwork, install, postinstall and unmount" >&2
 
-     ;;
 
- esac
 
 
  |