Introduction
Linux CIS Benchmarks require /home, /var, /var/tmp, /var/log, and
/var/log/audit to reside on separate partitions, each with mount options
(nodev, nosuid, noexec) that a shared root filesystem can't apply
selectively. This guide walks through resizing that root partition post-install
and creating the separate partitions the benchmarks require, without
reinstalling the system or losing data.
Warning: Resizing the root partition and creating new filesystems can be risky. While this guide aims to preserve existing data, unexpected issues may result in data loss. Always create and verify a backup before making changes.
Prerequisites
-
A Linux server, e.g. with Hetzner
-
A root partition with sufficient unallocated space available to accommodate the new partitions.
This guide uses:
-
A GPT-partitioned disk.
-
/dev/sdaas the disk device, and/dev/sda1as the root partition, formatted withext4. -
ext4for the five new partitions.
If your setup differs from the above, the corresponding commands throughout this guide must be adjusted accordingly.
This guide omits
/tmpand/dev/shm, as tmpfs can be mounted on both. Either can be added to the partitioning plan below if a disk-backed mount is desired instead.
Step 1 - Initial Preparation
-
Determine the target partition distribution before proceeding. The following is provided as an example and is the chosen distribution for this guide:
Partition Size /10 GiB /home10 GiB /var4 GiB /var/tmp2 GiB /var/log6 GiB /var/log/audit4 GiB Run
df -h /to check how much disk space is used on your root filesystem. -
Create the
/etc/growroot-disabledfile to prevent automatic root partition growth:sudo touch /etc/growroot-disabled -
Take a system snapshot for safety (strongly recommended).
-
Prior to entering rescue mode, record the current system state:
lsblk df -h cat /etc/fstab lsblk -dno pttype /dev/sda -
Enter the Rescue System, see guide for dedicated servers or guide for cloud servers.
Do not mount the root partition yet, as it must be resized first. If it is already mounted, unmount it with
umount.
Step 2 - Shrink the Root Partition
Before creating new partitions, you must shrink the existing root filesystem and partition.
Run lsblk -f to check the filesystem.
e2fsckandresize2fsapply only to the ext2/ext3/ext4 family of filesystems, a different filesystem requires the corresponding resize and check tooling.
First, force a check and repair of the root filesystem:
e2fsck -f -y /dev/sda1Shrink the ext4 filesystem to a size smaller than the target partition size
(8G here) to ensure a safety margin during partition resizing:
resize2fs /dev/sda1 8GUse parted to shrink the underlying partition to 10GiB:
parted /dev/sdaInside the parted shell:
(parted) resizepart 1 10GiB
Warning: Shrinking a partition can cause data loss, are you sure you want to continue?
Yes/No? yes
(parted) quitExpand the filesystem back to fill the newly resized 10GiB partition, and run
a final filesystem check:
resize2fs /dev/sda1
e2fsck -f -y /dev/sda1Step 3 - Create and Format New Partitions
With the root partition resized, create the separate partitions required by CIS benchmarks, using the distribution from Step 1:
The syntax below is specific to GPT partition tables and
ext4partitions. Where a different partition table or filesystem is in use, consultman partedand adapt the commands below accordingly. Runparted /dev/sda printto check which partition table and filesystem is used on your system.
parted -a optimal /dev/sda mkpart home ext4 10GiB 20GiB
parted -a optimal /dev/sda mkpart var ext4 20GiB 24GiB
parted -a optimal /dev/sda mkpart vartmp ext4 24GiB 26GiB
parted -a optimal /dev/sda mkpart varlog ext4 26GiB 32GiB
parted -a optimal /dev/sda mkpart varlogaudit ext4 32GiB 36GiBVerify the partition layout with lsblk. If the new partitions do not
appear immediately, trigger a kernel partition table re-read using partprobe /dev/sda. The numbering must be confirmed against what the subsequent commands
expect (sda2-sda6). Where the numbering differs, all following steps must be
adjusted accordingly.
Format each new partition with ext4 (substitute if a different filesystem was chosen):
mkfs.ext4 /dev/sda2
mkfs.ext4 /dev/sda3
mkfs.ext4 /dev/sda4
mkfs.ext4 /dev/sda5
mkfs.ext4 /dev/sda6Step 4 - Data Migration
Create temporary mount points for the old root filesystem and all target partitions:
mkdir -p /mnt/old_root /mnt/new_home /mnt/new_var /mnt/new_vartmp /mnt/new_varlog /mnt/new_varauditMount the original root partition and all target partitions:
mount /dev/sda1 /mnt/old_root
mount /dev/sda2 /mnt/new_home
mount /dev/sda3 /mnt/new_var
mount /dev/sda4 /mnt/new_vartmp
mount /dev/sda5 /mnt/new_varlog
mount /dev/sda6 /mnt/new_varauditThe CIS benchmarks' example specifies cp -a for this step. rsync -aHAX is
used instead, for simpler subdirectory exclusion when splitting /var across
multiple destinations below, and, unlike cp -a dir/* dest/, includes hidden
files (dotfiles), which glob-based invocations of cp omit by default.
rsync -aHAX /mnt/old_root/home/ /mnt/new_home/
rsync -aHAX /mnt/old_root/var/tmp/ /mnt/new_vartmp/
rsync -aHAX --exclude='tmp/' --exclude='log/' /mnt/old_root/var/ /mnt/new_var/
rsync -aHAX --exclude='audit/' /mnt/old_root/var/log/ /mnt/new_varlog/
[[ -d /mnt/old_root/var/log/audit ]] && rsync -aHAX /mnt/old_root/var/log/audit/ /mnt/new_varaudit/Verify that all files migrated cleanly:
ls -la /mnt/new_home/
ls -la /mnt/new_var/
ls -la /mnt/new_vartmp/
ls -la /mnt/new_varlog/
ls -la /mnt/new_varaudit/Step 5 - Cleanup and Directory Preparation
Remove the old /home and /var directories from the root volume to free up space:
rm -Rf /mnt/old_root/home/
rm -Rf /mnt/old_root/var/Recreate essential mount point directories:
mkdir -p /mnt/old_root/home
mkdir -p /mnt/old_root/var
mkdir -p /mnt/new_var/tmp
mkdir -p /mnt/new_var/log
mkdir -p /mnt/new_varlog/auditUnmount the new partitions:
umount /mnt/new_home
umount /mnt/new_var
umount /mnt/new_vartmp
umount /mnt/new_varlog
umount /mnt/new_varauditStep 6 - Configure /etc/fstab
Retrieve the filesystem UUIDs for the new partitions. Adjust the regex in the command if necessary:
blkid | grep -E "sda[2-6]"Partitions are referenced by UUID rather than device path, as device names
(/dev/sda2, etc.) are not guaranteed to remain stable across reboots or disk
changes.
Edit /mnt/old_root/etc/fstab (not the rescue system's /etc/fstab) and append
entries with the recommended CIS mount flags (make sure to place the respective
filesystem UUIDs). The 2 in the last field enables fsck checks on boot,
ordered after the root filesystem. See fstab(5):
UUID=<uuid-sda2> /home ext4 defaults,rw,nosuid,nodev,relatime 0 2
UUID=<uuid-sda3> /var ext4 defaults,rw,nosuid,nodev,relatime 0 2
UUID=<uuid-sda4> /var/tmp ext4 defaults,rw,nosuid,nodev,noexec,relatime 0 2
UUID=<uuid-sda5> /var/log ext4 defaults,rw,nosuid,nodev,noexec,relatime 0 2
UUID=<uuid-sda6> /var/log/audit ext4 defaults,rw,nosuid,nodev,noexec,relatime 0 2Run a syntax check against the modified configuration file:
findmnt --verify --fstab --tab-file /mnt/old_root/etc/fstabVerify that 0 parse errors are returned. Errors or warnings reporting
entries such as /var/log/audit as "unreachable" may still appear. These
do not indicate a fault, as findmnt evaluates reachability against the
rescue environment's filesystem, which does not contain the target system's
directories.
Step 7 - Unmount and Reboot
Unmount the old root partition and reboot back into the normal system:
umount /mnt/old_root
rebootStep 8 - Post-Reboot Verification
Once back inside the main system, verify active mount configurations:
mount | column -t
df -h
lsblk -fStep 9 - CIS Audits
Verify mount points and flags meet compliance standards:
findmnt -kn /home
findmnt -kn /var
findmnt -kn /var/tmp
findmnt -kn /var/log
findmnt -kn /var/log/auditEach mount must be confirmed to carry the flags required by the benchmark. For
each mount, grep -v applied to the expected flag must return no output:
findmnt -kn /home | grep -v nodev
findmnt -kn /home | grep -v nosuid
findmnt -kn /var | grep -v nodev
findmnt -kn /var | grep -v nosuid
findmnt -kn /var/tmp | grep -v nodev
findmnt -kn /var/tmp | grep -v nosuid
findmnt -kn /var/tmp | grep -v noexec
findmnt -kn /var/log | grep -v nodev
findmnt -kn /var/log | grep -v nosuid
findmnt -kn /var/log | grep -v noexec
findmnt -kn /var/log/audit | grep -v nodev
findmnt -kn /var/log/audit | grep -v nosuid
findmnt -kn /var/log/audit | grep -v noexecThe absence of output for a given check indicates the flag is present and correctly applied. Output indicates a failed check.
Step 10 - Troubleshooting
If your user directory was moved from /home to /var, move it back. Example:
Replace
holuwith your own username.
sudo find / -maxdepth 3 -type d -name holu 2>/dev/null
sudo ls -la /var/holu
sudo mkdir -p /home/holu
sudo rsync -aHAX /var/holu/ /home/holu/
sudo chown -R holu:holu /home/holu
ls -la /home/holu
sudo rm -rf /var/holuConclusion
This procedure results in /home, /var, /var/tmp, /var/log, and
/var/log/audit residing on separate partitions with the mount options required
by the CIS Benchmarks, verified in Step 9.