bootstrap-bookworm.sh 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #!/bin/bash -e
  2. #----------
  3. # Interactive installation steps for Debian Bullseye from GRML using debootstrap
  4. # Design decisions
  5. # - Fokus on a simple setup, primarly for VMs
  6. # - One disk, one partion, swap-file in the same partion as safety net
  7. # - Use systemd whereever possible (network, ntp, cron, journald logging)
  8. # - Minimal number of packages & cloud kernel
  9. # - grub-pc, not efi
  10. # - random root and admin user password generation
  11. # - ssh on port 50101 limited to the admin user
  12. # Usage
  13. # # Boot grml
  14. # passwd root
  15. # grml-network
  16. # Start ssh
  17. # git clone https://git.in-ulm.de/ulpeters/bootstrap.git
  18. # cp config.sh.template config.sh # copy template
  19. # config-get-netconf-eth0.sh # get running grml network config
  20. # vi config.sh # update installation variables
  21. # bootstrap-bullseye.sh install # start installation
  22. # !! Note down the admin passwords and reboot
  23. # sudo /installer/bootstrap-bullseye.sh postinstall # run postinstall in the new system
  24. # Variables
  25. mnt="/mnt/root" # mountpoint for the new root filesystem
  26. hostname="somehost.example.com"
  27. partition="single-mbr"
  28. disk="/dev/vda" # lsblk --list
  29. disk1=$disk"1"
  30. netDev="eth0" # ip link
  31. netAddress="203.0.113.66/24"
  32. netGateway="203.0.113.1"
  33. netBroadcast="203.0.113.255"
  34. netDNS1="192.0.2.10"
  35. netDNS2="198.51.100.10"
  36. netNTP="pool.ntp.org"
  37. extraPackages=""
  38. [ -f ./config.sh ] && source config.sh
  39. # Setup network in grml
  40. grmlnetwork(){
  41. ip link show # list interfaces
  42. ip addr add $netAddress dev $netDev
  43. ip link set $netDev up
  44. ip route add default via $netGateway
  45. echo nameserver $netDNS1 >> /etc/resolv.conf
  46. echo nameserver $netDNS2 >> /etc/resolv.conf
  47. }
  48. install(){
  49. if [ "$partition" = "single-mbr" ]
  50. then
  51. #----------
  52. # Prepare disks
  53. # Parition disks -- pkg: parted
  54. parted $disk -s \
  55. mklabel msdos \
  56. mkpart primary ext4 512M 100% toggle 1 boot
  57. fdisk -l $disk
  58. # Format disks -- pkg: e2fsprogs dosfstools and to file system check
  59. mkfs.ext4 $disk1 && e2fsck $disk1
  60. fi
  61. # Prepare mount points and mount
  62. mkdir -p $mnt
  63. mount $disk1 $mnt
  64. # Create swapfile
  65. swapfile=$mnt/swapfile
  66. dd if=/dev/zero of=$swapfile bs=1M count=1024 status=progress # create 1GB file
  67. chmod 600 $swapfile #restric permissions
  68. mkswap $swapfile #format file
  69. #----------
  70. # Bootstrap -- pkg: debootstrap
  71. # Remark: Debootstrap does not install recommands!!
  72. debootstrap --variant=minbase --arch=amd64 bookworm $mnt http://ftp2.de.debian.org/debian/
  73. #----------
  74. # Configuration
  75. # Configure disk mounts
  76. # Or get UUID from blkid...
  77. cat >$mnt/etc/fstab <<EOL
  78. $disk1 / ext4 rw 0 0
  79. /swapfile none swap defaults 0 0
  80. EOL
  81. # Configure sources.list
  82. cat >$mnt/etc/apt/sources.list <<EOL
  83. deb http://deb.debian.org/debian bookworm main non-free-firmware
  84. # deb-src http://deb.debian.org/debian bookworm main non-free-firmware
  85. deb http://deb.debian.org/debian-security/ bookworm-security main non-free-firmware
  86. # deb-src http://deb.debian.org/debian-security/ bookworm-security main non-free-firmware
  87. deb http://deb.debian.org/debian bookworm-updates main non-free-firmware
  88. # deb-src http://deb.debian.org/debian bookworm-updates main non-free-firmware
  89. EOL
  90. # Configure hostname
  91. echo "127.0.0.1 $hostname" >> $mnt/etc/hosts
  92. echo "$hostname" > $mnt/etc/hostname
  93. #----------
  94. # Prepare chroot
  95. mount -o bind /dev $mnt/dev
  96. mount -o bind /dev/pts $mnt/dev/pts
  97. mount -t sysfs /sys $mnt/sys
  98. mount -t proc /proc $mnt/proc
  99. cp /proc/mounts $mnt/etc/mtab
  100. cp /etc/resolv.conf $mnt/etc/resolv.conf
  101. mkdir -p $mnt/installer
  102. cp $(dirname `realpath $0`)/*.sh $mnt/installer
  103. # Run script in chroot
  104. chroot $mnt /bin/bash /installer/bootstrap-bullseye.sh install2
  105. # Install bootloader
  106. $0 bootloader
  107. }
  108. #----------
  109. # Function executed within chroot
  110. install2(){
  111. source /installer/config.sh
  112. # Install basic system
  113. apt-get update
  114. apt-get install --yes \
  115. apt-utils dialog msmtp-mta \
  116. systemd-sysv locales tzdata haveged \
  117. linux-image-cloud-amd64 grub-pc \
  118. iproute2 netbase \
  119. ssh sudo molly-guard \
  120. less vim-tiny bash-completion pwgen lsof \
  121. dnsutils iputils-ping curl \
  122. $extraPackages
  123. # Upgrade and clean up
  124. apt-get upgrade --yes
  125. apt-get autoremove --yes
  126. apt-get clean --yes
  127. # Setup users and passwords
  128. [ -z $pwdAdmin ] && pwdAdmin=`pwgen --capitalize --numerals --ambiguous 12 1`
  129. useradd admin --create-home --shell /bin/bash
  130. echo "admin:$pwdAdmin" | chpasswd
  131. usermod -a -G sudo admin
  132. echo -e "\e[1;33;4;44mPassword for the user admin: $pwdAdmin\e[0m"
  133. pass=`pwgen --capitalize --numerals --ambiguous 12 1`
  134. [ -z $pwdRoot ] && pwdRoot=`pwgen --capitalize --numerals --ambiguous 12 1`
  135. echo "root:$pwdRoot" | chpasswd
  136. echo -e "\e[1;33;4;44mPassword for the user root: $pwdRoot\e[0m"
  137. # Harden SSHD
  138. sed -i -e 's/#Port 22/Port 50101/g' /etc/ssh/sshd_config
  139. sed -i -e 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/g' /etc/ssh/sshd_config
  140. # https://infosec.mozilla.org/guidelines/openssh.html
  141. # Allow admin to sudo without password
  142. echo AllowUsers admin >> /etc/ssh/sshd_config
  143. echo "admin ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/admin
  144. ## Configure network using systemd
  145. if [ -z $netAddress ]
  146. then
  147. ## Network OPTION 1 - DHCP
  148. cat >/etc/systemd/network/20-wired.network <<EOL
  149. [Match]
  150. Name=e*
  151. [Network]
  152. DHCP=ipv4
  153. IPv6PrivacyExtensions=false
  154. IPv6AcceptRA=false
  155. NTP=$netNTP
  156. EOL
  157. else
  158. ## Network OPTION 2 - static
  159. cat >/etc/systemd/network/20-wired.network <<EOL
  160. [Match]
  161. Name=$netDev
  162. [Network]
  163. Address=$netAddress
  164. Gateway=$netGateway
  165. Broadcast=$netBroadcast
  166. DNS=$netDNS1
  167. DNS=$netDNS2
  168. NTP=$netNTP
  169. EOL
  170. fi
  171. ## Setup systemd resolver
  172. apt-get install --yes systemd-resolved
  173. echo -e "\n# Disable local name resolution" >> /etc/systemd/resolved.conf
  174. echo "LLMNR=no" >> /etc/systemd/resolved.conf
  175. echo "MulticastDNS=no" >> /etc/systemd/resolved.conf
  176. systemctl enable systemd-networkd
  177. systemctl enable systemd-resolved
  178. # Limit journald logging to 1 month, 1 GB in total and split files per week
  179. mkdir -p /etc/systemd/journald.conf.d/
  180. cat >/etc/systemd/journald.conf.d/retention.conf <<EOL
  181. MaxRetentionSec=1month
  182. SystemMaxUse=1G
  183. MaxFileSec=1week
  184. EOL
  185. # Show errors in motd
  186. rm /etc/motd
  187. cat >/etc/update-motd.d/15-boot-errors<<EOL
  188. #!/bin/sh
  189. echo
  190. journalctl --boot --priority=3 --no-pager
  191. EOL
  192. chmod 755 /etc/update-motd.d/15-boot-errors
  193. # Setup keyboard layout
  194. cat >/etc/default/keyboard <<EOL
  195. XKBMODEL="pc105"
  196. XKBLAYOUT="de"
  197. XKBVARIANT="nodeadkeys"
  198. XKBOPTIONS=""
  199. BACKSPACE="guess"
  200. EOL
  201. # Leave chroot
  202. exit
  203. }
  204. bootloader(){
  205. # Install GRUB in /dev/vba
  206. chroot $mnt /bin/bash -c "grub-install $disk && update-grub"
  207. }
  208. unmount(){
  209. # Unmount if mounted
  210. ! mountpoint -q $mnt/proc || umount $mnt/proc
  211. ! mountpoint -q $mnt/sys || umount $mnt/sys
  212. ! mountpoint -q $mnt/dev/pts || umount $mnt/dev/pts
  213. ! mountpoint -q $mnt/dev || umount $mnt/dev
  214. ! mountpoint -q $mnt/root || umount $mnt/root
  215. ! mountpoint -q $mnt || umount $mnt
  216. # Delete mount-point if empty and not mounted
  217. [ -z "$(ls -A /mnt/)" ] && ! mountpoint -q $mnt && rm -R $mnt
  218. }
  219. postinstall(){
  220. ####----REBOOT into the new system, so we'll have dbus running
  221. localectl set-locale LANG=de_DE.UTF-8 # Default for LC_* variables not set.
  222. localectl set-locale LC_MESSAGES=en_US.UTF-8 # System messages.
  223. #localectl set-locale LC_RESPONSE=en_US.UTF-8 # How responses (such as Yes and No) appear
  224. update-locale
  225. timedatectl set-timezone Europe/Berlin
  226. }
  227. # Switch to functions...
  228. case $1 in
  229. grmlnetwork)
  230. echo Setup network in grml
  231. grmlnetwork
  232. ;;
  233. install)
  234. echo "Stage 1: Start installation"
  235. install
  236. ;;
  237. install2)
  238. echo "Stage 2: Start installation in chroot"
  239. install2
  240. ;;
  241. bootloader)
  242. echo "Stage 3: Install bootloader and unmount chroot"
  243. bootloader
  244. unmount
  245. echo "We're done and can reboot now"
  246. ;;
  247. postinstall)
  248. echo "Stage 4: Start post-installation in live system"
  249. postinstall
  250. ;;
  251. unmount)
  252. echo "Unmount chroot, e.g. in case installation fails"
  253. unmount
  254. ;;
  255. *)
  256. echo "Valid functions are: grmlnetwork, install, postinstall and unmount" >&2
  257. ;;
  258. esac