If you rent a root server, you sometimes want to install your own operating system. Maybe because you want to know exactly what was installed there - or because the provider does not offer the desired operating system.

The article shows the installation of Debian Stretch on a root server (here in the Strato data center). Most root server vendors do not allow you to insert a virtual CD as an ISO image, so you cannot install your own Linux the regular way.

Prerequisite is that you can boot another Linux (means with Strato Rescue System / Recovery Manager) and you should be able to see the messages of the server (with Stratro: serial console).

Here are the necessary commands, the details should be self-explanatory for Linux admins. Who would like to know it in more detail, can read this article: Read Installing Debian8 Jessie by Bootstap on Strato Rootserver, there the necessary steps are described in more detail.

Comments and commands are located here together within a large block, as this makes it easier for you to copy out multiple commands.

#Updating package lists
#Install the "parted" package
apt-get update && apt-get install parted -y

#Create an empty GPT partition scheme on both disks
dd if=/dev/zero of=/dev/sda bs=1M count=1
dd if=/dev/zero of=/dev/sdb bs=1M count=1

#Reboot
reboot -n

#Updating package lists
#Install the "parted" and other package
apt-get update && apt-get install parted debootstrap host -y

#Check if the two disks are empty (without partitions)
parted -l 

#Creating partitions on /dev/sda
parted -s /dev/sda mklabel gpt
parted -s /dev/sda mkpart primary 1 100M
parted -s /dev/sda mkpart primary 100M 33G
parted -s /dev/sda mkpart primary 33G  184G
parted -s /dev/sda mkpart primary 184G 1584G
parted -s /dev/sda mkpart primary 1584G 100%
parted -s /dev/sda set 1 bios_grub on
parted -s /dev/sda set 2 raid on
parted -s /dev/sda set 3 raid on
parted -s /dev/sda set 4 raid on
parted -s /dev/sda set 5 raid on

#Creating partitions on /dev/sdb
parted -s /dev/sdb mklabel gpt
parted -s /dev/sdb mkpart primary 1M 100M
parted -s /dev/sdb mkpart primary 100M 33G
parted -s /dev/sdb mkpart primary 33G  184G
parted -s /dev/sdb mkpart primary 184G 1584G
parted -s /dev/sdb mkpart primary 1584G 100%
parted -s /dev/sdb set 1 bios_grub on
parted -s /dev/sdb set 2 raid on
parted -s /dev/sdb set 3 raid on
parted -s /dev/sdb set 4 raid on
parted -s /dev/sdb set 5 raid on

#Check for the presence of the partitions just created
parted -l 

#Creating the Software Raid Mirrors
mdadm --create /dev/md2 --level=mirror --raid-devices=2 /dev/sda2 /dev/sdb2 --metadata 1.2 --bitmap=none
mdadm --create /dev/md3 --level=mirror --raid-devices=2 /dev/sda3 /dev/sdb3 --metadata 1.2 --bitmap=internal
mdadm --create /dev/md4 --level=mirror --raid-devices=2 /dev/sda4 /dev/sdb4 --metadata 1.2 --bitmap=none
mdadm --create /dev/md5 --level=mirror --raid-devices=2 /dev/sda5 /dev/sdb5 --metadata 1.2 --bitmap=internal

#Check if the synchronization of the raid arrays has started
cat /proc/mdstat

#Creating SWAP and file systems
mkswap /dev/md2
mke2fs -t ext4  /dev/md3
mke2fs -t ext4  /dev/md4
mke2fs -t ext4  /dev/md5

#Mount the raid arrays and create the currently required directories
mount /dev/md3 /mnt/
mkdir /mnt/home /mnt/usr /mnt/var /mnt/boot /mnt/boot/grub /mnt/etc /mnt/tmp /mnt/dev /mnt/proc /mnt/sys /mnt/mnt /mnt/root /mnt/backuppartition
chmod 700 /mnt/root /mnt/backuppartition
chmod 777 /mnt/tmp
chmod +t /mnt/tmp
mount /dev/md4 /mnt/var
mount /dev/md5 /mnt/backuppartition

#create the file fstab
my_array=()
while IFS= read -r line; do
    my_array+=( "$line" )
done < <( blkid | grep md | awk '{print $1,$2}' | sort )

md2=`echo ${my_array[0]} | awk '{print $2}'`" none swap defaults,pri=1 0 0 #"`echo ${my_array[0]} | awk '{print $1}' |cut -f1 -d:`
md3=`echo ${my_array[1]} | awk '{print $2}'`" / ext4 defaults,errors=remount-ro 0 1 #"`echo ${my_array[1]} | awk '{print $1}' |cut -f1 -d:`
md4=`echo ${my_array[2]} | awk '{print $2}'`" /var ext4 defaults,usrquota  0 2 #"`echo ${my_array[2]} | awk '{print $1}' |cut -f1 -d:`
md5=`echo ${my_array[3]} | awk '{print $2}'`" /backuppartition ext4 defaults  0 2 #"`echo ${my_array[3]} | awk '{print $1}' |cut -f1 -d:`

echo 'proc /proc proc defaults 0 0' >  /mnt/etc/fstab
echo $md2 >>  /mnt/etc/fstab
echo $md3 >>  /mnt/etc/fstab
echo $md4 >>  /mnt/etc/fstab
echo $md5 >>  /mnt/etc/fstab


#Run Debian9 bootstrap in /mnt (installing the base system)
debootstrap --arch amd64 stretch /mnt http://ftp.de.debian.org/debian

#Chroot into the newly installed Debian9
#mount /dev and /sys into chroot
mount --bind /dev /mnt/dev
mount -t sysfs /sys /mnt/sys

#chroot
chroot /mnt

#make pro available
mount -tproc none /proc
mount -t devpts devpts -o noexec,nosuid,gid=5,mode=620 /dev/pts

#Creating a password for root
#Attention, to access via SSH another user or the deposit of a certificate is necessary.
#At Strato, however, we can access it from the serial console and do this later.
passwd

#Creating the package sources for apt
echo 'deb http://httpredir.debian.org/debian stretch main contrib non-free' > /etc/apt/sources.list
echo 'deb-src http://httpredir.debian.org/debian stretch main contrib non-free' >> /etc/apt/sources.list
echo 'deb http://httpredir.debian.org/debian stretch-updates main contrib non-free' >> /etc/apt/sources.list
echo 'deb-src http://httpredir.debian.org/debian stretch-updates main contrib non-free' >> /etc/apt/sources.list
echo 'deb http://security.debian.org/ stretch/updates main contrib non-free' >> /etc/apt/sources.list
echo 'deb-src http://security.debian.org/ stretch/updates main contrib non-free' >> /etc/apt/sources.list
echo 'deb http://httpredir.debian.org/debian  stretch-backports main contrib non-free' >> /etc/apt/sources.list

#Update package lists
apt-get update

#Installation of some important packages and the kernel
#Some of these packages should already be in the system through the bootstrap, like dbus and systemd
apt-get install locales grub2 mdadm udev ssh host isc-dhcp-client pciutils vim molly-guard locate systemd dbus keyboard-configuration linux-image-amd64 firmware-linux firmware-linux-nonfree memtest86 net-tools man -y

#Enable serial console support
#systemctl enable getty@ttyS0.service

#Set hostname and mailname
#Set reverse DNS first at Strato and wait for TTL
#This command only works for hostnames with this schema: server.domain.tld
host `ip addr show eth0 | grep "inet " | awk '{print $2}' | cut -f1 -d/`|  awk '{print $5}' | cut -d. -f1,2,3

#Is the hostname correct? Then we set this as hostname and mailname
host `ip addr show eth0 | grep "inet " | awk '{print $2}' | cut -f1 -d/`|  awk '{print $5}' | cut -d. -f1,2,3 > /etc/hostname
host `ip addr show eth0 | grep "inet " | awk '{print $2}' | cut -f1 -d/`|  awk '{print $5}' | cut -d. -f1,2,3 > /etc/mailname

#Activate DHCP for eth0
#Under Debian9 the file /etc/network/interfaces is still used despite systemd
echo "auto lo" > /etc/network/interfaces
echo "iface lo inet loopback" >> /etc/network/interfaces
echo "auto eno1" >> /etc/network/interfaces
echo "iface eno1 inet dhcp" >> /etc/network/interfaces

#Setting up bootloader for serial console
sed -i  's|GRUB_CMDLINE_LINUX_DEFAULT="quiet"|GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,57600"|' /etc/default/grub
sed -i  's|#GRUB_TERMINAL=console|GRUB_TERMINAL=serial|' /etc/default/grub
sed -i  's|GRUB_TIMEOUT=5|GRUB_TIMEOUT=60|' /etc/default/grub
echo 'GRUB_SERIAL_COMMAND="serial --speed=57600 --unit=0 --word=8 --parity=no --stop=1"' >> /etc/default/grub

#Create a new Grub configuration
grub-mkconfig
update-grub

#Allow SSHD login with password
sed -i 's|#PermitRootLogin prohibit-password|PermitRootLogin yes|g' /etc/ssh/sshd_config


#Logging Out and Rebooting
exit
reboot -n