This guide explains how to install the Void Linux on OVH VPS. This might also work for other VPS providers with the proper rescue system in place.
Table of contents:
- 1. Rescue mode
- 2. Partitioning
- 3. Rootfs tarball deployment
- 4. Chroot
- 5. Base system
- 6. System settings
- 7. GRUB bootloader installation
- 8. Finish
- 9. Post-installation
- 10. Troubleshooting
Log into OVHcloud, switch to your VPS control panel, select Boot -> Restart into Rescue Mode. It takes up to 3 minutes to boot into rescue mode. You can read the rescue root account password from KVM (Console) or from the link sent via email.
Let's copy our SSH Key into the rescue environment first for convenience and log in:
if [ ! -e ~/.ssh/id_ed25519 ] ; then ssh-keygen -t ed25519 ; fi
ssh-copy-id [email protected]
ssh [email protected]
Check available drives:
fdisk -l
[RESCUE] root@vps-XXXXXXXX:~ $ fdisk -l
Disk /dev/sda: 2.93 GiB, 3145728000 bytes, 6144000 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x9fdc479eDevice Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 6141951 6139904 2.9G 83 LinuxDisk /dev/sdb: 40 GiB, 42949672960 bytes, 83886080 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xbb326e04Device Boot Start End Sectors Size Id Type
/dev/sdb1 * 2048 83886079 83884032 40G 83 Linux
We are interested in /dev/sdb, which is our VPS's drive.
Partitioning is up to you. You can follow the official documentation at https://docs.voidlinux.org/installation/live-images/partitions.html. In this case, I have simply created one partition with boot flag on the legacy BIOS/MBR table.
A procedure is:
wipefs -a /dev/sdb
fdisk /dev/sdb
n
enter x 5 times
a
enter
w
enter
fdisk -l /dev/sdb
Welcome to fdisk (util-linux 2.37.2).
(...)Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p):Using default response p.
Partition number (1-4, default 1):
First sector (2048-83886079, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-83886079, default 83886079):Created a new partition 1 of type 'Linux' and of size 40 GB.
Command (m for help): a
Selected partition 1
The bootable flag on partition 1 is enabled now.Command (m for help): w
The partition table has been altered.
Syncing disks.
Format a newly created partition:
mkfs.ext4 /dev/sdb1
Now that we have our partition ready we can mount it and deploy rootfs. You'll find the latest rootfs image at https://voidlinux.org/download/. I'm using rootfs tarball glibc in this example.
mount /dev/sdb1 /mnt
cd /mnt
wget https://repo-default.voidlinux.org/live/current/void-x86_64-ROOTFS-20230628.tar.xz
tar -xvf void-x86_64-ROOTFS-20230628.tar.xz
rm void-x86_64-ROOTFS-20230628.tar.xz
Here we basically follow chroot installation as described here: https://docs.voidlinux.org/installation/guides/chroot.html
Prepare and switch into the chroot env:
mount -t proc proc /mnt/proc
mount -t sysfs sys /mnt/sys
mount -o bind /dev /mnt/dev
mount -t devpts pts /mnt/dev/pts
chroot /mnt
Update xbps and install the system's base:
echo "nameserver 1.1.1.1" > /etc/resolv.conf
xbps-install -Su xbps
xbps-install -u
xbps-install base-system
xbps-remove base-voidstrap
Set the hostname, root password and timezone at your discretion:
echo "example" > /etc/hostname
sed -i 's/localhost.localdomain/example/g;' /etc/hosts
passwd
echo "Europe/Warsaw" > /etc/timezone
ln -s /usr/share/zoneinfo/Europe/Warsaw /etc/localtime
GRUB setup:
xbps-install -S grub
grub-install /dev/sdb
grub-mkconfig -o /boot/grub/grub.cfg
bash-5.2# grub-mkconfig -o /boot/grub/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.5.13_1
Found initrd image: /boot/initramfs-6.5.13_1.img
Warning: os-prober will not be executed to detect other bootable partitions.
Systems on them will not be added to the GRUB boot configuration.
Check GRUB_DISABLE_OS_PROBER documentation entry.
done
That's it, you can exit chroot, unmount everything and restart the server:
exit
cd /root
cp -r /root/.ssh /mnt/root/
rm -f /mnt/root/.ssh/authorized_keys2
umount /mnt/{dev/pts,dev,sys,proc}
umount /mnt
sync
Now restart your VPS via the OVH control panel ($ reboot won't work).
You should see the Void Linux booting in the KVM (Console):
Install some useful tools:
xbps-install -S \
bash-completion \
bind-utils \
binutils \
curl \
cronie \
git \
htop \
iftop \
logrotate \
lsof \
lynis \
nano \
ncdu \
neofetch \
net-tools \
mc \
mtr \
unzip \
rsync \
rsyslog \
screen \
tcpdump \
vim \
wget \
whois \
xz
In order to enable sshd and dhcp on boot, create symlinks as described here: https://docs.voidlinux.org/config/services/index.html#enabling-services.
ln -s /etc/sv/dhcpcd /var/service/
ln -s /etc/sv/sshd /var/service/
If you've decided to install rsyslogd and/or cronie:
ln -s /etc/sv/rsyslogd /var/service/
ln -s /etc/sv/cronie /var/service/
Services will start automatically. You can control them with sv(8).
The IPv4 address will be set automatically by DHCP and you can now log into your server:
ssh-keygen -R X.X.X.X
ssh [email protected]
Should you choose to set the IPv6, you can do it like so:
echo "ip link set eth0 up" >> /etc/rc.local
echo "ip -6 a a IPv6_ADDRESS/128 dev eth0" >> /etc/rc.local
echo "ip -6 r a IPv6_GATEWAY dev eth0" >> /etc/rc.local
echo "ip -6 r a default via IPv6_GATEWAY dev eth0" >> /etc/rc.local
grep ^ip /etc/rc.local | while read -r x ; do $x ; done
Test IPv6:
ping -6 -c 1 google.com
It's a good idea to set up a firewall. You can do it using iptables.
Put the IPv4/IPv6 rules into the corresponding files:
- /etc/iptables/iptables.rules
- /etc/iptables/ip6tables.rules
Enable firewall:
ln -sv /etc/sv/iptables /var/service # IPv4
ln -sv /etc/sv/ip6tables /var/service # IPv6
Good examples of the iptables configuration:
- https://gist.github.com/jirutka/3742890#file-rules-ipv4-iptables
- https://github.com/trimstray/iptables-essentials
xbps-install chrony
ln -s /etc/sv/chronyd /var/service
You may also want to switch your shell and set PS1:
usermod -s /bin/bash root
cp /etc/skel/.* ./
source .bashrc
cat /proc/mounts | grep sda >> /etc/fstab
https://docs.voidlinux.org/config/kernel.html#blacklisting-modules-in-the-initramfs
for module in dccp sctp rds tipc firewire-ohci firewire-sbp2 pcspkr joydev floppy; do echo "blacklist $module" >> /etc/modprobe.d/blacklist.conf ; done
echo 'omit_drivers+=" dccp sctp rds tipc firewire-ohci firewire-sbp2 pcspkr joydev floppy "' > /etc/dracut.conf.d/blacklist.conf
xbps-reconfigure -f linux6.5 # check uname -a and change kernel version accordingly
Requires rsyslogd (or some other log daemon)
xbps-install fail2ban
sed -i 's/#allowipv6/allowipv6/g;' /etc/fail2ban/fail2ban.conf
mkdir /etc/fail2ban/jail.d
echo -e "[sshd]\nenabled = true\nlogpath = /var/log/messages" > /etc/fail2ban/jail.d/sshd.conf
ln -s /etc/sv/fail2ban /var/service/
OSSEC is a multiplatform, open source and free Host Intrusion Detection System (HIDS).
You can get the latest version at https://www.ossec.net/download-ossec/
xbps-install gcc make openssl-devel pcre-devel pcre2-devel zlib-devel
wget https://github.com/ossec/ossec-hids/archive/3.7.0.tar.gz
tar -xvf 3.7.0.tar.gz
cd ossec-hids-3.7.0
USE_SYSTEMD=no ./install.sh
/var/ossec/bin/ossec-control start
echo '/var/ossec/bin/ossec-control start >/dev/null' >> /etc/rc.local # autostart on boot
https://docs.voidlinux.org/installation/live-images/partitions.html#swap-partitions
If you haven't created it earlier, it might be a good idea to create a swap file to avoid OOM stepping in.
fallocate -l 2G /swap
chmod 600 /swap
mkswap /swap
/swap none swap sw 0 0 >> /etc/fstab
swapon -a
xbps-install easyrsa openvpn
cd /etc/easyrsa
./easyrsa init-pki
./easyrsa build-ca
./easyrsa build-server-full server1 nopass
./easyrsa build-client-full client1 nopass
./easyrsa gen-dh
openvpn --genkey secret ./pki/ta.key
mkdir /etc/openvpn
mkdir /var/log/openvpn
You will find example configs here: /usr/share/examples/openvpn/
/etc/openvpn/server.conf
local X.X.X.X
port 1194
# protocols: IPv4: udp, tcp; IPv6: udp6, tcp-server
proto tcp
dev tun
ca /etc/easyrsa/pki/ca.crt
cert /etc/easyrsa/pki/issued/server1.crt
key /etc/easyrsa/pki/private/server1.key
dh /etc/easyrsa/pki/dh.pem
topology subnet
server 10.0.0.0 255.255.255.0
#server-ipv6 fd00::1/64
ifconfig-pool-persist /var/log/openvpn/ipp.txt
keepalive 10 120
tls-auth /etc/easyrsa/pki/ta.key 0
data-ciphers AES-256-GCM
auth SHA512
tls-version-min 1.3
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
To start the server as a runit service:
mkdir /etc/sv/openvpn
echo '#!/bin/sh' > /etc/sv/openvpn/run
echo 'exec openvpn --config /etc/openvpn/server.conf' >> /etc/sv/openvpn/run
chmod 755 /etc/sv/openvpn/run
ln -s /etc/sv/openvpn /var/service
client.conf
client
dev tun
# protocols: IPv4: udp, tcp; IPv6: udp6, tcp-client
proto tcp
remote X.X.X.X 1194
resolv-retry infinite
nobind
#ifconfig-ipv6 fd00::2 fd00::1
user nobody
group nogroup
persist-key
persist-tun
ca ca.crt
cert client1.crt
key client1.key
remote-cert-tls server
tls-auth ta.key 1
data-ciphers AES-256-GCM
auth SHA512
tls-version-min 1.3
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256
verb 3
On the client side you'll need to copy ca.crt, ta.key, client1.crt and client1.key from the server:
- /etc/easyrsa/pki/ca.crt
- /etc/easyrsa/pki/ta.key
- /etc/easyrsa/pki/issued/client1.crt
- /etc/easyrsa/pki/private/client1.key
Connect with:
openvpn --config client.conf
https://community.openvpn.net/openvpn/wiki/IPv6
If you want to switch to a IPv6 VPN instead, replace server with server-ipv6 accordingly on the server side:
#server 10.0.0.0 255.255.255.0
server-ipv6 fd00::1/64
Also replace local/remote addresses and proto in both server/client configs from IPv4 to IPv6.
xbps-install docker docker-buildx docker-compose
ln -s /etc/sv/docker /var/service
docker run hello-world
Consider paranoya - Simple IOC and YARA scanner
xbps-install -Su
[*] Updating repository `https://repo-de.voidlinux.org/current/x86_64-repodata' ...
Certificate verification failed for /C=US/O=Internet Security Research Group/CN=ISRG Root X1
SSL_connect returned 1
ERROR: [reposync] failed to fetch file `https://repo-de.voidlinux.org/current/x86_64-repodata': Operation not permitted
If you know that the error occurred after you made changes to the system, reinstall the CA and openssl certificates with SSL_NO_VERIFY_PEER=true env:
SSL_NO_VERIFY_PEER=true xbps-install -f ca-certificates openssl
Otherwise, make sure nothing is wrong with the repo or certificate.
If you're looking for more info, head over to https://docs.voidlinux.org/.
If you found this article helpful, please consider making donation to a charity on my behalf. Thank you.
Enjoy your Void Linux adventure!