#!/bin/bash # # System installer. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public # License along with this program. If not, see # . # Load. source $APP_BASE/lib/hydra/functions || exit 1 hydra_config_load # Create a logical volume function hydra_lvcreate { local volume="$1" local size="$2" local space if [ -z "$volume" ] || [ "$size" == "0" ]; then return fi if ! lvdisplay $vg/$volume &> /dev/null; then echo "Creating logical volume $volume..." # See http://forums.funtoo.org/viewtopic.php?id=1206 # https://bbs.archlinux.org/viewtopic.php?id=124615 #hydra_safe_run lvcreate -Z n -L$size -n $volume $vg if [ "$size" == "-1" ]; then space="-l %FREE" else space="-L $size" fi hydra_safe_run lvcreate $space -n $volume $vg fi } # Create a physical volume function hydra_create_volume { local volume="$1" if [ -z "$volume" ] || [ ! -b "/dev/mapper/$vg-$volume" ]; then return fi if [ "$encrypt" == "y" ]; then echo "Creating encrypted $volume device..." hydra_safe_run cryptsetup -h sha256 -c aes-cbc-essiv:sha256 -s 256 luksFormat /dev/mapper/$vg-$volume hydra_safe_run cryptsetup luksOpen /dev/mapper/$vg-$volume $volume hydra_safe_run mkfs.ext4 /dev/mapper/$volume if [ "$volume" == "root" ]; then install_device="/dev/mapper/root" fi else echo "Creating $volume device..." mkfs.ext4 /dev/mapper/$vg-$volume if [ "$volume" == "root" ]; then install_device="/dev/mapper/$vg-root" fi fi } # Setup. hydra_user_input device /dev/sdb "Destination device" hydra_user_input root_size 20G "Size of root partition" hydra_user_input swap_size 2000 "Swap size (in MB, 0 to not create it)" hydra_user_input home_size 20G "Size of home partition (0 to not create it, -1 for all free space)" hydra_user_input var_size 20G "Size of var partition (0 to not create it, -1 for all free space)" hydra_user_input encrypt y "Encrypt volumes? (y/n)" hydra_user_input garbage y "Pre-fill volumes with garbage? (y/n)" hydra_user_input hostname $HOSTNAME "Hostname" hydra_user_input domain example.com "Domain" hydra_user_input arch amd64 "System arch" hydra_user_input version wheezy "Distro version" hydra_user_input vg vg "Temporary install vg" hydra_user_input grub y "Setup GRUB? (y/n)" hydra_user_input mirror http://http.debian.net/debian/ "Debian mirror" # Check for requirements. for req in debootstrap cryptsetup grub-pc lvm2 parted; do hydra_install_package $req done # Warning. cat <<-EOF WARNING: about to partition $device! Press ENTER to continue, Ctrl-C to abort." EOF read answer # Disk partitioning. if [ "$swap" != "0" ]; then boot_end=$(($swap_size + 200)) hydra_safe_run parted -s -- $device mklabel msdos hydra_safe_run parted -s -- $device unit MB mkpart primary linux-swap 2 $swap_size hydra_safe_run parted -s -- $device unit MB mkpart primary ext2 $swap_size $boot_end hydra_safe_run parted -s -- $device unit MB mkpart primary ext2 $boot_end -1 hydra_safe_run parted -s -- $device set 2 boot on hydra_safe_run parted -s -- $device set 3 lvm on # Change devices to absolute path names. swap_device="$device"1 boot_device="$device"2 syst_device="$device"3 else hydra_safe_run parted -s -- $device mklabel msdos hydra_safe_run parted -s -- $device unit MB mkpart primary ext2 2 200 hydra_safe_run parted -s -- $device unit MB mkpart primary ext2 200 -1 hydra_safe_run parted -s -- $device set 1 boot on hydra_safe_run parted -s -- $device set 2 lvm on # Change devices to absolute path names. boot_device="$device"1 syst_device="$device"2 fi # Create volumes. echo "Creating the needed disk volumes..." if ! pvdisplay $syst_device &> /dev/null; then echo "Creating physical volume..." hydra_safe_run pvcreate $syst_device fi if ! vgdisplay $vg &> /dev/null; then echo "Creating volume group..." hydra_safe_run vgcreate $vg $syst_device fi hydra_safe_run vgdisplay hydra_safe_run vgchange -a y $vg hydra_lvcreate root $root_size hydra_lvcreate home $home_size hydra_lvcreate var $var_size # Garbage. if [ "$garbage" == "y" ]; then echo "Filling volumes with garbage..." dd if=/dev/urandom of=/dev/mapper/$vg-root if [ -b "/dev/mapper/$vg-home" ]; then dd if=/dev/urandom of=/dev/mapper/$vg-home fi if [ -b "/dev/mapper/$vg-var" ]; then dd if=/dev/urandom of=/dev/mapper/$vg-var fi if [ "$swap" != "0" ]; then dd if=/dev/urandom of=$swap_device fi fi # Setup mountpoint and make sure it's not mounted due to a failed install. mkdir -p /tmp/debootstrap umount /tmp/debootstrap &> /dev/null for folder in proc dev home var boot sys; do umount /tmp/debootstrap/$folder &> /dev/null done # Create devices hydra_create_volume root hydra_create_volume home hydra_create_volume var # Mount root volume hydra_safe_run mount $install_device /tmp/debootstrap/ # Mount additional volumes if [ "$home_size" != "0" ]; then mkdir /tmp/debootstrap/home if [ "$encrypt" == "y" ]; then hydra_safe_run mount /dev/mapper/home /tmp/debootstrap/home else hydra_safe_run mount /dev/mapper/$vg-home /tmp/debootstrap/home fi fi if [ "$var_size" != "0" ]; then mkdir /tmp/debootstrap/var if [ "$encrypt" == "y" ]; then hydra_safe_run mount /dev/mapper/var /tmp/debootstrap/var else hydra_safe_run mount /dev/mapper/$vg-var /tmp/debootstrap/var fi fi # Initial system install. echo "Installing base system..." hydra_safe_run debootstrap --arch=$arch $version /tmp/debootstrap/ $mirror # Initial configuration. echo "Applying initial configuration..." mount none -t proc /tmp/debootstrap/proc mount none -t sysfs /tmp/debootstrap/sys mount -o bind /dev/ /tmp/debootstrap/dev echo LANG=C > /tmp/debootstrap/etc/default/locale # Resolver configuration. echo "domain $domain" > /tmp/debootstrap/etc/resolv.conf echo "search $hostname.$domain" >> /tmp/debootstrap/etc/resolv.conf grep nameserver /etc/resolv.conf >> /tmp/debootstrap/etc/resolv.conf # Hostname configuration. echo $hostname.$domain > /tmp/debootstrap/etc/hostname echo "127.0.0.1 localhost" >> /tmp/debootstrap/etc/hosts echo "127.0.0.1 $hostname $hostname.$domain" >> /tmp/debootstrap/etc/hosts # Invert hostname contents to avoid http://projects.puppetlabs.com/issues/2533 tac /tmp/debootstrap/etc/hosts > /tmp/debootstrap/etc/hosts.new mv /tmp/debootstrap/etc/hosts.new /tmp/debootstrap/etc/hosts # Initial upgrade. echo "Applying initial upgrades..." chroot /tmp/debootstrap/ apt-get update chroot /tmp/debootstrap/ apt-get upgrade -y chroot /tmp/debootstrap/ apt-get install locales cryptsetup lvm2 initramfs-tools -y # Crypttab. echo "Configuring crypttab..." echo "# " > /tmp/debootstrap/etc/crypttab if [ "$encrypt" == "y" ]; then cat > /tmp/debootstrap/etc/crypttab <<-EOF root /dev/mapper/vg-root none luks,cipher=aes-cbc-essiv:sha256 EOF fi if [ "$home_size" != "0" ] && [ "$encrypt" == "y" ]; then cat >> /tmp/debootstrap/etc/crypttab <<-EOF home /dev/mapper/vg-home none luks,cipher=aes-cbc-essiv:sha256 EOF fi if [ "$var_size" != "0" ] && [ "$encrypt" == "y" ]; then cat >> /tmp/debootstrap/etc/crypttab <<-EOF var /dev/mapper/vg-var none luks,cipher=aes-cbc-essiv:sha256 EOF fi if [ "$swap" != "0" ]; then cat >> /tmp/debootstrap/etc/crypttab <<-EOF cswap $swap_device /dev/random swap,cipher=aes-cbc-essiv:sha256 EOF fi # Fstab. echo "Configuring fstab..." echo "" > /tmp/debootstrap/etc/fstab if [ "$swap" != "0" ]; then cat >> /tmp/debootstrap/etc/fstab <<-EOF /dev/mapper/cswap none swap sw 0 0 EOF fi if [ "$encrypt" == "y" ]; then cat > /tmp/debootstrap/etc/fstab <<-EOF /dev/mapper/root / ext4 defaults,errors=remount-ro 0 1 EOF else cat > /tmp/debootstrap/etc/fstab <<-EOF /dev/mapper/vg-root / ext4 defaults,errors=remount-ro 0 1 EOF fi if [ "$home_size" != "0" ]; then if [ "$encrypt" == "y" ]; then cat >> /tmp/debootstrap/etc/fstab <<-EOF /dev/mapper/home /home ext4 defaults,errors=remount-ro 0 2 EOF else cat >> /tmp/debootstrap/etc/fstab <<-EOF /dev/mapper/vg-home /home ext4 defaults,errors=remount-ro 0 2 EOF fi fi if [ "$var_size" != "0" ]; then if [ "$encrypt" == "y" ]; then cat >> /tmp/debootstrap/etc/fstab <<-EOF /dev/mapper/var /var ext4 defaults,errors=remount-ro 0 2 EOF else cat >> /tmp/debootstrap/etc/fstab <<-EOF /dev/mapper/vg-var /var ext4 defaults,errors=remount-ro 0 2 EOF fi fi # Grub. if [ "$grub" == "y" ]; then echo "Boot device setup..." hydra_safe_run mkfs.ext4 $boot_device hydra_safe_run mount $boot_device /tmp/debootstrap/boot echo "$boot_device /boot ext4 defaults,errors=remount-ro 0 2" >> /tmp/debootstrap/etc/fstab echo "Setting up GRUB..." hydra_safe_run chroot /tmp/debootstrap/ apt-get install grub-pc -y fi # Kernel. echo "Installing kernel..." cat > /tmp/debootstrap/etc/initramfs-tools/modules <<-EOF dm-mod dm-crypt aes twofish sha256 EOF cat > /tmp/debootstrap/etc/kernel-img.conf <<-EOF do_initrd = Yes EOF if [ "$arch" == "i386" ]; then kernel_arch="686" else kernel_arch="$arch" fi if [ "$version" == "squeeze" ]; then hydra_safe_run chroot /tmp/debootstrap apt-get install linux-image-2.6-vserver-$kernel_arch -y else hydra_safe_run chroot /tmp/debootstrap apt-get install linux-image-$kernel_arch -y fi # Initramfs. echo "Creating initramfs..." hydra_safe_run chroot /tmp/debootstrap update-initramfs -v -u # Utils. echo "Installing basic utilities..." chroot /tmp/debootstrap apt-get install screen cron lsb-release openssl -y # Ssh. echo "Installing OpenSSH daemon..." chroot /tmp/debootstrap apt-get install openssh-server -y echo "OpenSSH fingerprints:" chroot /tmp/debootstrap ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub chroot /tmp/debootstrap ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub # Accounts. echo "Installing sudo..." chroot /tmp/debootstrap apt-get install sudo -y echo "Choose a root password." chroot /tmp/debootstrap passwd root cat <<-EOF Now proceeed with final steps: - Create an user account with sudo privileges. - Network setup. See http://padrao.sarava.org/install for more information. EOF