I really like Gentoo for their awesome package manager, Portage. Gentoo is a really flexible distribution that you can customize (and break) in many ways. It’s a good opportunity to learn a lot about linux. I documented the installation process. Given is an EX server from Hetzner, booted into the Debian rescue system.
As a first step, we setup the partitioning + mdadm Raid + LVM + filesystems:
parted /dev/nvme0n1 --script mklabel gpt parted /dev/nvme1n1 --script mklabel gpt parted /dev/nvme0n1 --script mkpart primary ext3 2048s 4095s parted /dev/nvme1n1 --script mkpart primary ext3 2048s 4095s parted /dev/nvme0n1 --script mkpart primary ext3 4096s 1953791s parted /dev/nvme1n1 --script mkpart primary ext3 4096s 1953791s parted /dev/nvme0n1 --script mkpart primary ext3 1953792s 100% parted /dev/nvme1n1 --script mkpart primary ext3 1953792s 100% parted /dev/nvme0n1 --script set 1 bios_grub on parted /dev/nvme1n1 --script set 1 bios_grub on mdadm --verbose --create /dev/md/0 --level=1 --raid-devices=2 --metadata=1.2 /dev/nvme0n1p2 /dev/nvme1n1p2 mdadm --verbose --create /dev/md/1 --level=1 --raid-devices=2 --metadata=1.2 /dev/nvme0n1p3 /dev/nvme1n1p3 echo 999999999 > /proc/sys/dev/raid/speed_limit_min echo 999999999 > /proc/sys/dev/raid/speed_limit_max until ! grep -q resync /proc/mdstat; do echo "sleeping for 2s"; sleep 2; done mkfs.ext4 -v /dev/md/1 pvcreate --verbose /dev/md/2 vgcreate --verbose vg0 /dev/md/2 lvcreate --verbose --name root --size 50G vg0 mkfs.ext4 -v /dev/mapper/vg0-root mount /dev/mapper/vg0-root /mnt/
Next, we download a stage 3 tarball (minimal precompiled Gentoo basically) and verify it:
url='https://mirror.netcologne.de/gentoo/releases/amd64/autobuilds/current-stage3-amd64-systemd' latest='stage3-amd64-systemd-20220102T170545Z.tar.xz' for file in '' {.CONTENTS.gz,.DIGESTS.asc}; do wget "${url}/${latest}${file}"; done gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 0xBB572E0E2D182910 gpg --verify "${latest}.DIGESTS.asc" grep " ${latest}.CONTENTS.gz" *.DIGESTS.asc openssl dgst -r -sha512 "${latest}.CONTENTS.gz"
This will verify the gpg signature in the .asc File. Afterwards we grep the SHA512 checksum for CONTENTS.gz from the .asc file. Then we run openssl to compute the SHA512 checksum on the actual stage 3. Compare the two SHA512 checksums, they have to be identical. If they are, continue with extracting the tarball:
mv stage3-amd64-hardened-selinux-*.tar.xz /mnt/ cd /mnt/ tar xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner mount /dev/md/1 /mnt/boot/
Now we can prepare the chroot:
cp --dereference /etc/resolv.conf /mnt/etc/ mount --types proc /proc /mnt/proc mount --rbind /sys /mnt/sys mount --make-rslave /mnt/sys mount --rbind /dev /mnt/dev mount --make-rslave /mnt/dev mkdir /mnt/hostlvm mount --bind /run/lvm /mnt/hostlvm chroot /mnt/gentoo /bin/bash ln -s /hostlvm /run/lvm source /etc/profile export PS1="(chroot) ${PS1}"
Now we can configure portage:
mkdir /etc/portage/repos.conf cp /usr/share/portage/config/repos.conf /etc/portage/repos.conf/gentoo.conf echo 'MAKEOPTS="-j6"' >> /etc/portage/make.conf echo 'USE="systemd ipv6"' >> /etc/portage/make.conf sed -i 's/^COMMON_FLAGS.*/COMMON_FLAGS="-march=native -O2 -pipe"/g' /etc/portage/make.conf emerge --sync emerge --ask --verbose --update --deep --newuse @world emerge --depclean echo '=sec-policy/selinux-base-policy-9999 **' >> /etc/portage/package.accept_keywords # set profile to hardened..., see eselect profile list emerge --ask --verbose --unmerge sysvinit eudev echo 'sys-fs/mdadm static' >> /etc/portage/package.use/mdadm echo 'sys-fs/lvm2 lvm2create_initr' >> /mnt/etc/portage/package.use/lvm2 echo 'app-admin/puppet augeas diff doc rrdtool' > /etc/portage/package.use/puppet emerge --ask --autounmask-write --verbose sys-kernel/gentoo-sources sys-apps/systemd vim htop nload iftop iptraf-ng strace lsof gentoolkit intel-microcode pciutils genkernel dstat grub mdadm lvm2 smartmontools dropbear ccze fail2ban tcpdump dev-vcs/git puppet dfc gptfdisk ethtool net-misc/ipcalc ndisc6 echo 'LANG="en_US.utf8"' >> /etc/locale.conf # setup /etc/systemd/network/50-dhcp.network mdadm --detail --scan >> /etc/mdadm.conf sed -i 's/.*LVM=.*/LVM="yes"/' /etc/genkernel.conf sed -i 's/.*MICROCODE=.*/MICROCODE="yes"/' /etc/genkernel.conf sed -i 's/.*SSH=.*/SSH="yes"/' /etc/genkernel.conf sed -i 's/.*BUSYBOX=.*/BUSYBOX="yes"/' /etc/genkernel.conf sed -i 's/.*MDADM=.*/MDADM="yes"/' /etc/genkernel.conf sed -i 's/.*E2FSPROGS=.*/E2FSPROGS="yes"/' /etc/genkernel.conf genkernel all sed -i 's/.*GRUB_DISABLE_SUBMENU.*/GRUB_DISABLE_SUBMENU=y/g' /etc/default/grub sed -i 's/.*GRUB_TIMEOUT=.*/GRUB_TIMEOUT=15/g' /etc/default/grub sed -i 's|.*#GRUB_CMDLINE_LINUX=.*|GRUB_CMDLINE_LINUX="init=/usr/lib/systemd/systemd dolvm domdadm dossh rootfstype=ext4"|' /etc/default/grub for dev in /dev/nvme?n1; do grub-install "${dev}"; done grub-mkconfig -o /boot/grub/grub.cfg # get UUID with `blkid /dev/mapper/vg0-root /dev/md1` and update /etc/fstab passwd mkdir ~/.ssh echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKC4uaKuYzMGK4jlTvPlbnMP9n+gdac65480/eDTMWRw bastelfreak" > ~/.ssh/authorized_keys sed -i 's/.*PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config systemctl enable systemd-networkd sshd
Setup language/locales
echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen # verify that our locale is present: locale -a | grep en_US.utf8 eselect locale set en_US.utf8 echo 'dns_domain_lo="bastelfreak.org"' >> /etc/conf.d/net echo 'hostname="hypervisor01"' >> /etc/conf.d/hostname . /etc/profile env-update && source /etc/profile
Setup timesyncd and DNS
sed -i 's/#NTP=/NTP=ntp1.hetzner.de ntp2.hetzner.com ntp3.hetzner.net/' /etc/systemd/timesyncd.conf rm /etc/localtime ln -s /usr/share/zoneinfo/Europe/Berlin /etc//localtime sed -i 's/#DNS=/DNS=2a01:4f8:0:1::add:1010 2a01:4f8:0:1::add:9999 2a01:4f8:0:1::add:9898/' /etc/systemd/resolved.conf sed -i 's/#Domains=/Domains=bastelfreak.org/' /etc/systemd/resolved.conf systemctl enable systemd-timesyncd systemd-resolved
Now we can reboot! I suggest to configure a password first and/or create a user. After the first boot we can continue with some fancy pancy stuff:
Setup LLDP:
echo 'net-misc/lldpd jansson' > /etc/portage/package.use/lldpd emerge --ask lldpd systemctl enable lldpd systemctl start lldpd
Setup all the fancy dotfiles:
cd ~ git clone https://github.com/bastelfreak/scripts.git ln -s ~/scripts/vimrc ~/.vimrc ln -s ~/scripts/bashrc ~/.bashrc ln -s ~/scripts/bash_profile ~/.bash_profile mkdir -p ~/.vim/backupdir/ mkdir ~/.vim/ftplugin echo "set colorcolumn=80" >> ~/.vim/ftplugin/tex.vim git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim vim +PluginInstall +qall
And last but not least, you might want to run some virtual machines, so install Qemu and Libvirt:
echo 'app-emulation/libvirt zeroconf virt-network pcap parted lvm' > /etc/portage/package.use/libvirt echo 'app-emulation/qemu spice virtfs usb usbredir' > /etc/portage/package.use/qemu emerge --ask qemu libvirt ebtables dmidecode openvswitch bridge-utils dispatch-conf emerge --ask qemu libvirt ebtables dmidecode openvswitch bridge-utils systemctl enable ovsdb-server systemctl start ovsdb-server systemctl start ovs-vswitchd systemctl enable ovs-vswitchd ovs-vsctl add-br br0
You now have a proper Gentoo box. I suggest to configure at least backups and a firewall. Please keep in mind that Gentoo is a rolling release distribution, so some of the commands might be obsolete after some time or you need to configure something differently. Still, this walkthrough should give you a good first impression.