System hardening is the practice of deliberately locking down the underlying operating system and the Linux kernel to eliminate unnecessary vulnerabilities before an attacker can exploit them. For the CKS exam, you must understand that even a perfectly configured Kubernetes cluster can be compromised if the host OS beneath it has weak passwords, open ports, or misconfigured kernel parameters. Mastering this concept means you can prevent attacks that target the server itself, not just the containers running on it.
Jump to a section
A simple way to picture System Hardening: Host OS and Kernel Security
A busy restaurant kitchen on a Friday night. The head chef, Maria, has just received a health inspector warning about a nearby place that got shut down after a rat infestation and a gas leak. She decides to harden her own kitchen before it is too late.
First, she installs heavy-duty screens on every window and door — not just the main entrance. These screens are like the kernel parameters that control how the operating system handles network traffic. She blocks any ventilation shaft wider than a centimetre, which is like disabling unused ports and services on the host OS. She then fits all electrical sockets with childproof covers so that only specific plugs can fit — this mirrors setting filesystem permissions and using mandatory access controls like AppArmor or SELinux to restrict what processes can do.
Next, Maria creates a strict logbook for deliveries. Every supplier must sign in, and any ingredients left unattended get thrown out. This is analogous to auditing and logging all system calls and changes to critical system files. She assigns each chef a specific coloured apron: red for the grill, blue for pastries, green for vegetables. If a chef in a red apron tries to enter the pastry station, an alarm sounds. That is exactly what kernel security modules do — they enforce rules about which users and programs can interact with which resources.
Finally, she removes all but one key to the walk-in freezer and gives it only to herself. That single lock is like the principle of least privilege applied to the root account: only the admin gets the master key, and even then, only when absolutely necessary. The kitchen stays open, the food is safe, and the inspectors leave happy. Your host OS and kernel are that kitchen: they need the same kind of obsessive, layered defence to keep attackers out.
When you run Kubernetes, every node is a physical or virtual server running an operating system — almost always Linux. The operating system, or host OS, manages all the hardware resources and runs all the software. The kernel is the absolute core of that operating system, a piece of software that controls everything: memory, CPU, devices, and network traffic. System hardening means making both the host OS and the kernel as resistant to attack as possible.
Let us start with the host OS. A fresh installation of Linux comes with thousands of programs, services, and features enabled by default. Many of these are unnecessary for running Kubernetes. For example, a service called CUPS lets you print documents. On a server that never prints anything, CUPS is just a potential entry point for an attacker. The same goes for things like FTP servers, email services, or the X Window System graphical interface. Hardening means removing or disabling every service, package, and user account that is not absolutely required. This is often called reducing the attack surface.
Next come kernel parameters. The Linux kernel has hundreds of settings you can adjust using a tool called sysctl. These parameters control behaviours as fundamental as how the kernel responds to network traffic, how memory is allocated, and how processes communicate with each other. For security, you want to apply a set of known-safe values. For example, you can set a parameter that prevents a process from gaining more privileges than it was originally given — this is called preventing privilege escalation. You can set another parameter that stops a user from seeing processes owned by other users, which prevents one person's container from spying on another's. These parameters live in files under /proc/sys/ and can be changed at runtime.
A critical part of kernel hardening is using Linux Security Modules (LSMs) like AppArmor or SELinux. These are kernel features that enforce security policies on individual programs. Imagine you run a web server container. AppArmor can say: this web server can only read files in /var/www/html, can only open port 80, and can never run other programs. If an attacker compromises the web server and tries to run a shell command, AppArmor blocks it at the kernel level. SELinux works similarly but uses a more complex system of labels and rules. The CKS expects you to know how to enable and configure these tools.
Another major area is filesystem hardening. The host OS has a filesystem that stores all its files. You can set permissions so that only the root user can write to critical directories like /etc or /usr. You can also mount filesystems with special options: for example, mounting a partition as read-only means nothing can be written to it, even by the root user. Kubernetes itself uses container images that are often read-only, but the host's filesystem must also be locked down. You should also ensure that the filesystem itself is encrypted, typically using LUKS (Linux Unified Key Setup), so that even if a hard drive is stolen, the data cannot be read.
Finally, system hardening covers user accounts and authentication. By default, Linux has many system accounts that you never use. You should lock them. You should enforce strong password policies, use key-based SSH authentication instead of passwords, and configure sudo so that only specific users can run privileged commands. The principle of least privilege applies everywhere: every user and every process should get exactly the permissions it needs to do its job, and nothing more. Together, these measures make it vastly harder for an attacker to move from a compromised container to the host operating system or from the host to other machines on the network.
Inventory Current State
Log into the node and run commands like ps aux, netstat -tulpn, and systemctl list-units to see all running processes, open ports, and active services. This gives you a complete picture of what is running so you know what to disable or remove.
Remove Unnecessary Packages and Services
Use the package manager (apt for Debian/Ubuntu, yum for RHEL) to purge packages that are not needed, such as CUPS, FTP, or mail servers. Disable and stop services with systemctl disable and systemctl stop. This shrinks the attack surface by eliminating unused software that could harbour vulnerabilities.
Apply Secure Kernel Parameters
Create a file like /etc/sysctl.d/99-security.conf and add parameters that prevent privilege escalation, restrict kernel memory access, and improve network security. Then run sysctl --system to apply them. These parameters modify how the kernel behaves at runtime to thwart common exploit techniques.
Configure Mandatory Access Control (MAC)
Choose AppArmor or SELinux, then create and load a security profile that restricts what a specific process (e.g., nginx) can do. For AppArmor, write a profile file and load it with apparmor_parser. For Kubernetes, annotate the Pod to apply the profile. This prevents a compromised container from damaging the host.
Harden User Accounts and SSH
Lock unused system accounts with usermod -L, delete unnecessary users with userdel, and edit /etc/ssh/sshd_config to disable root login and password-based authentication. Restart the SSH service. This ensures that only authorised users with strong keys can access the node.
Set Filesystem Permissions and Mount Options
Edit /etc/fstab to add mount options like noexec, nodev, and nosuid to partitions like /tmp or /var/tmp where attackers might write scripts. Also set correct ownership and permissions on critical directories like /etc/shadow so only root can read them. This stops attackers from executing malicious code or escalating privileges via writable locations.
Enable Auditing and Logging
Install and configure auditd, add rules to log important events (e.g., changes to /etc/passwd, failed login attempts), and ensure logs are forwarded to a central system. This provides a record of any security incidents and helps with forensic analysis after an attack.
Imagine you are the new security engineer at a mid-sized e-commerce company. The company runs its entire product catalogue, checkout system, and customer database on a Kubernetes cluster spread across 10 nodes. The nodes are virtual machines running Ubuntu Server. Your boss tells you that a penetration test last month found that an attacker could break out of a container and gain root access to the host node. You have been tasked with hardening every single node.
Your first step is to audit the current configuration. You SSH into one node and run a command like ps aux to see all running processes. You see a dozen services you do not recognise. You check which network ports are open using netstat -tulpn and find that port 25 (used for email) is listening — but the company does not send email from these nodes. You also see that FTP is running, which is a huge risk because FTP sends passwords in plaintext. You document everything and create a plan.
Next, you begin removing unnecessary packages. On each node, you use the package manager apt to remove packages like cups, vsftpd, and postfix. You also purge any unused GUI components because a headless server does not need a desktop environment. After removal, you run a tool called Lynis, which is an open-source security auditing tool, to check for common misconfigurations. It flags that the root account is accessible via SSH. You edit the SSH configuration file /etc/ssh/sshd_config to set PermitRootLogin no and then restart the SSH service.
Now you tackle kernel parameters. You create a file called /etc/sysctl.d/99-kubernetes-security.conf and add parameters that the Kubernetes documentation recommends. For example, you set net.ipv4.conf.all.rp_filter = 1 to enable reverse path filtering, which helps prevent IP spoofing. You set kernel.kptr_restrict = 2 to hide kernel pointers from unprivileged users. You set kernel.dmesg_restrict = 1 so that only root can read kernel log messages. After adding all the parameters, you run sysctl --system to apply them immediately.
Then you configure AppArmor. The company uses an nginx web server container. You create an AppArmor profile that restricts nginx to only reading files in its own webroot, binding to port 80 and 443, and never running executables. You load the profile into the kernel using apparmor_parser. You then modify the Kubernetes Pod specification to include an annotation that tells the container runtime to apply that AppArmor profile. You deploy the change and verify that the profile is loaded using aa-status.
Finally, you enable auditing with auditd. You configure rules that log every time someone tries to change the system time, every failed login attempt, and every modification to critical files in /etc. You also set up log forwarding so that all audit logs go to a central Security Information and Event Management (SIEM) system. When the next penetration test happens, the tester finds that container breakout is now impossible, and the host OS is completely locked down. Your boss approves the changes and you document everything for the compliance team.
The CKS exam is intensely practical, and the System Hardening section (Objective 4.1) directly tests your ability to secure a Linux host that runs Kubernetes. You will not be asked to write essays — you will be given a terminal on a cluster node and asked to fix misconfigurations or apply specific settings.
Here are the exact concepts the exam tests repeatedly:
Kernel parameter hardening using sysctl: You must know which parameters are important and how to make them persistent. The exam often gives you a node where kernel parameters are insecure, and you must create a configuration file in /etc/sysctl.d/ and reload it. Common parameters include net.ipv4.ip_forward (set to 0 if not needed), net.bridge.bridge-nf-call-iptables (set to 1 for Kubernetes networking), and kernel.panic (set to a value like 10 to auto-reboot on kernel panic).
AppArmor profiles: You must be able to create, load, and apply an AppArmor profile to a Pod. The exam will give you a scenario where a container needs restricted access. You must write a profile using the apparmor_parser command, then add the correct annotation to the Pod YAML. The trap is that beginners forget to load the profile before applying the Pod, or they use the wrong syntax for the annotation.
Filesystem permissions and mount options: You might be asked to mount a filesystem with the noexec option to prevent binaries from being executed on a partition, or to set a directory as read-only (ro). The exam tests your knowledge of /etc/fstab and the mount command. A common trap is forgetting that the noexec option does not apply to scripts executed by /bin/sh — you must also use nodev and nosuid.
Removing unnecessary packages and services: The exam may present a node with a known insecure service running, like telnet or rsh. You need to stop the service and remove the package. They test whether you know the difference between apt remove (keeps config files) and apt purge (removes everything). They also check if you disable the service from starting at boot using systemctl disable.
User account hardening: Expect a question where you must lock a system account (usermod -L), delete an unnecessary user (userdel), or change the SSH configuration to disable root login and password authentication. A common trap is editing the SSH config but forgetting to restart the sshd service.
The exam loves to create scenarios where you have a node that is fully patched but still vulnerable because of a misconfigured kernel parameter or an unused service. The correct answer pattern is always to identify the security issue, apply the fix using the correct command or configuration file, and then verify the change. Memorise the specific sysctl parameter names and the AppArmor annotation format (container.apparmor.security.beta.kubernetes.io/containername: localhost/profilename). You will also need to know how to check audit logs using ausearch or aureport. Do not waste time on overly complex attacks — the exam focuses on straightforward, documented best practices.
System hardening reduces the attack surface by removing every unnecessary service, user, and open port from the host operating system.
Kernel parameters set via sysctl control fundamental security behaviours like IP forwarding, memory pointer hiding, and process privilege escalation prevention.
AppArmor and SELinux are Linux Security Modules that enforce mandatory access control policies at the kernel level, restricting what a process can do even if it has root privileges.
To make kernel parameters permanent, write them to a file in /etc/sysctl.d/ and run sysctl --system — never rely on sysctl -w alone.
The principle of least privilege applies to every user, process, and container: grant only the permissions needed for the specific task.
Auditing with auditd allows you to log all security-relevant events on the host, which is essential for detecting and investigating breaches.
Filesystem mount options like noexec, nodev, and nosuid prevent attackers from running malicious binaries or creating device files on specific partitions.
Always use apt purge instead of apt remove when deleting unnecessary software packages to eliminate their configuration files as well.
These come up on the exam all the time. Here's how to tell them apart.
sysctl -w (runtime change)
Applies immediately but only for the current session
Lost after a system reboot
Useful for testing a parameter before making it permanent
/etc/sysctl.d/ file (persistent change)
Applies on every boot, survives reboots
Must be loaded with sysctl --system after creation
Standard practice for production systems
AppArmor
Uses path-based policy rules (e.g., allow read on /etc/passwd)
Profile syntax is simpler and easier to read
Commonly used on Debian/Ubuntu distributions
SELinux
Uses label-based policy rules (e.g., allow httpd_t to read etc_t)
More complex configuration with booleans and contexts
Commonly used on RHEL/CentOS distributions
apt remove
Removes the package binary but leaves configuration files on the system
Configuration files can still be a security risk or cause confusion
Faster if you might reinstall the package later
apt purge
Removes both the package and all its configuration files
Cleaner outcome for security hardening
Prevents leftovers from being exploited or interfering
Disabling root login in SSH
Stops direct SSH login as the root user
Users must still login as a regular user and then use sudo
Alone, it does not protect against brute-force attacks on other users
Disabling password authentication in SSH
Stops all password-based authentication, forcing SSH key use only
Prevents brute-force attacks against any user account
Combined with root login disabled, provides strong SSH security
Mistake
I only need to harden the control plane nodes; worker nodes are less important.
Correct
Every node in a Kubernetes cluster, including worker nodes, must be hardened because a compromised worker node can give an attacker access to the entire cluster network and allow them to pivot to the control plane.
Beginners often think the control plane is the only valuable target, but containers running on worker nodes can be exploited to reach other containers and the host itself.
Mistake
Setting kernel parameters with sysctl -w makes the change permanent.
Correct
Using sysctl -w only changes the value until the next reboot. To make changes persistent, you must write them to a file in /etc/sysctl.d/ or /etc/sysctl.conf and run sysctl --system.
The transient nature of runtime changes is counterintuitive to people used to GUI settings that stay saved; they do not realise Linux kernel parameters reset at boot.
Mistake
AppArmor and SELinux are the same thing and interchangeable.
Correct
While both are Linux Security Modules, AppArmor uses path-based policies (e.g., allow read on /etc/passwd) and SELinux uses label-based policies (e.g., allow httpd_t to read etc_t files). They have different configuration syntaxes and tools.
The names sound similar and both enforce mandatory access control, so beginners assume they can use whichever with the same commands, which leads to errors on exam tasks.
Mistake
If I uninstall a service with apt remove, it is completely gone from the system.
Correct
apt remove leaves configuration files behind. You must use apt purge to remove both the package and its configuration files, otherwise leftover config can still be a risk or cause confusion.
The word 'remove' sounds final, but the default behaviour in Debian-based systems is to preserve config files in case you reinstall the package.
Mistake
Disabling root login via SSH is enough to secure SSH access.
Correct
Disabling root login is important, but you also need to disable password authentication entirely and use only SSH keys, set a maximum authentication retries limit, and use AllowUsers or AllowGroups to restrict who can connect.
People focus on the root account but forget that any user with a weak password can still be compromised via SSH brute-force attacks.
Mistake
Kernel hardening is only about network parameters.
Correct
Kernel hardening covers many areas including memory protection (kptr_restrict, dmesg_restrict), privilege escalation prevention (kernel.unprivileged_userns_clone), filesystem security (fs.protected_hardlinks, fs.protected_symlinks), and execution control (kernel.exec-shield).
Network parameters are the most obvious and well-documented, so learners often stop there and miss critical non-network settings.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
Host OS hardening locks down the underlying Linux server itself — its kernel, services, user accounts, and filesystem — while container hardening focuses on the container image and runtime. Both are needed because a weak host can compromise all containers running on it.
No, the CKS exam typically tests one of them depending on the distribution provided. You should understand both conceptually, but the exam tasks will specify which one is available. AppArmor is more common on Ubuntu-based clusters, while SELinux is common on CentOS or RHEL.
You must write the settings to a file in the /etc/sysctl.d/ directory (e.g., /etc/sysctl.d/99-custom.conf) and then run sysctl --system to reload them. Changes made with sysctl -w alone are lost on reboot.
It controls whether unprivileged users can see kernel memory addresses in /proc files and other interfaces. Setting it to 2 hides those addresses from everyone except root, which makes it harder for an attacker to craft reliable exploit payloads.
No, patching only fixes known vulnerabilities in existing software. System hardening is about removing unnecessary software and restricting behaviour so that even unpatched components cannot be exploited effectively. You must do both.
Most security parameters apply universally, but some may interfere with Kubernetes functionality. For example, net.ipv4.ip_forward must be set to 1 for pod-to-pod communication, and net.bridge.bridge-nf-call-iptables must be set to 1 for iptables to work correctly with bridge traffic. Test changes in a staging environment first.
You've finished System Hardening: Host OS and Kernel Security. Continue through the CKS study guide to build a complete picture of the exam.
Done with this chapter?