RHCSA Practice Labs¶
These are a collection of labs that will cover essential RHCSA study points.
Doing these labs will be a great way to get hands-on with the tools we'll be using in the RHCSA exam.
Snapshots
It is highly recommended to take a snapshot of your VM before starting any of
these labs.
This will allow you to revert back to a clean state if you make a mistake.
Configuring Apache Webserver && SELinux Contexts¶
This lab will have us set up and configure an Apache web server on a non-standard port, use a non-standard directory for web site files, and configure SELinux to make the Apache config work, as well as allow remote access.
The lab scenario is as follows.
Scenario¶
Your company wants Apache configured with the following requirements:
- Apache must listen on TCP port
8081. - Website files must be stored under
/srv/rhcsa-web. -
The website must display:
-
/srv/rhcsa-web/uploadsmust be writable by Apache. - Remote clients must be able to access port
8081. - SELinux must remain enforcing.
- Everything must persist across a reboot.
Do not solve SELinux problems by:
- Disabling SELinux
- Leaving SELinux permissive
- Using
chconas the permanent solution - Generating a custom policy with
audit2allow
Use SELinux the correct way. Set contexts and booleans properly. This will help to gain a deeper understanding of Apache and SELinux (and will be expected on the RHCSA exam).
It's highly recommended to attempt the lab before looking at the solution.
Solution Part 1: Setting up Apache
-
Ensure the necessary packages are installed.
-
Create the custom document root.
-
Create the web page that will be served.
Add the following text to that file.
-
Set the ordinary Linux permissions on the file.
-
Create the Apache configuration file.
The config file should be as follows.
-
Check the syntax of the Apache webserver config.
Look for
Syntax OK.
Now Apache is set up to serve the custom document root on port 8081.
The next steps will require setting SELinux contexts on the new document
root directory, enabling a specific SELinux boolean, and allowing access
through Firewalld.
Solution Part 2: SELinux Configuration
-
After Apache is set up, attempt to start it.
This will fail. SELinux doesn't normally permit
httpd_tto bind to port8081. -
Allow Apache to serve on port
8081through SELinux.
semanage port: The tool used to manage port mappings for SELinux.-a: Add a new port mapping.-t http_port_t: Specify the type ashttp_port_tfor this mapping.-p tcp: Specify the protocol astcp.8081: The port to apply this rule to.- Side note: This is actually an example in
man semanage-port. Remember that for the exam.
-
Set the proper contexts on the custom document root directory.
-
Check the current contexts of the files and directories.
They should be as follows:
-
Check the default Apache files' contexts to see what needs to be changed.
The directory itself:
Thesystem_u:object_r:httpd_sys_content_t:s0 . system_u:object_r:var_t:s0 .. system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin system_u:object_r:httpd_sys_content_t:s0 htmlhttpd_sys_content_ttype is needed for the Apache files. -
Add the context for the custom document root.
-
Set the SELinux boolean to allow
httpdconnections remotely.
semanage boolean: One of the tools that can modify SELinux booleans.-m: Modify an existing boolean.--on: Set the boolean toon.httpd_can_network_connect: The name of the boolean to modify.-
This can also be done with the other tools that SELinux provides to interact with booleans.
-P: Persists across reboots. This is the default behavior when usingsemanage boolean.
-
Configuring Autofs/NFS¶
Scenario¶
Your organization has an NFS server named:
nfs-server.lab.example.com
It exports the directories:
/srv/nfs/projects/srv/nfs/users/alice/srv/nfs/users/bob
Our lab had the following configurations:
rhel-node1: NFS Server. -192.168.4.75 nfs-server.lab.example.com nfs-serverrhel-node2: NFS Client -192.168.4.20 node1.lab.example.com node1
The /etc/hosts on both nodes were modified to include these lines.
Requirements¶
Configure the client so that:
- The
projectsshare appears at/shares/projects. - User directories appear dynamically under
/remotehome. - Accessing
/remotehome/alicemounts Alice’s directory. - Accessing
/remotehome/bobmounts Bob’s directory. - Mounts are read-only.
- Inactive mounts expire after 30 seconds.
- Configuration persists across reboots.
- No NFS entries are added to
/etc/fstab.
Task 1: Preflight checks¶
Determine whether:
- The NFS server resolves by name.
- The NFS server is reachable.
- Its exports are visible.
- The required client packages are installed.
Task 2: Projects indirect map¶
Configure autofs so that accessing:
mounts:Requirements:¶
- Use an indirect map.
- Mount it read-only using NFSv4.
- Use a 30-second inactivity timeout.
Task 3: Wildcard user map¶
Configure a wildcard map so that:
mounts: and: mounts:Do not create a separate map entry for every username.
Task 4: Persistence¶
Ensure autofs:
- Is running immediately.
- Starts automatically at boot.
- Still works following a reboot.
Task 5: Demonstrate on-demand behavior¶
Show that:
- The NFS share is not mounted initially.
- Accessing the path triggers the mount.
- Leaving the path and waiting causes the NFS mount to expire.
- Accessing it again remounts it.
Do not remain inside the automounted directory while testing expiration. As long as the directory is being accessed (e.g., a shell has that directory as it's working directory), the mount will remain active.
Solution
This solution assumes that the NFS server is already set up.
Task 1: Preflight checks¶
Determine whether:
-
The required client packages are installed.
-
The NFS server resolves by name.
-
The NFS server is reachable.
- It is possible that the firewall on the NFS server will block the ICMP
packets that come from
ping, so even if this fails, the server may still be reachable.
- It is possible that the firewall on the NFS server will block the ICMP
packets that come from
-
Its exports are visible.
showmount -eshows any exported shares from the given endpoint.
Task 2: Projects indirect map¶
Configure autofs so that accessing /shares/projects mounts:
Requirements:¶
- Use an indirect map.
- Mount it read-only using NFSv4.
- Use a 30-second inactivity timeout.
Solution:¶
-
Add an entry in
Using/etc/auto.masterthat will point/sharesto a key in another file. This is the workflow to create an indirect map.
.sharesfor the/sharesmountpoint is a typical naming convention.- The
-t 30ensures a 30-second timeout, meeting the last requirement.
- The
-
Create the
auto.sharesfile and define its mapping.-
projects: This is a "key" for theauto.masterentry, not necessarily a path. Accessing/shares/projectswill dynamically create all directories needed. -
-fstype=nfs4,ro: Set the filesystem type to NFS4 with read-only permissions. -
nfs-server.lab.example.com:/srv/nfs/shares/projects: This is the remote endpoint that will be mounted.
-
Task 3: Wildcard user map¶
Configure a wildcard map so that /remotehome/alice mounts:
/remotehome/bob mounts:
Do not create a separate map entry for every username.
Solution¶
-
Create a similar entry to the
Add the following mapping.sharesentry in/etc/auto.master, but point it to a different file.
-
Create the
/etc/auto.usersfile.
-
Add the mapping using a wildcard.
*: This is the wildcard. It will match any local path accessed in/remotehome.&: This is the placeholder for any matched directories on the NFS share.- This way, any newly created
usersdirectories in the NFS share will be accessible without needing to add more
Task 4: Persistence¶
Ensure autofs:
- Is running immediately.
- Starts automatically at boot.
- Still works following a reboot.
Solution¶
Simply enable/start the service.
Task 5: Demonstrate on-demand behavior¶
This is mostly a verification step.
Show that:
-
The NFS share is not mounted initially.
-
There should be no mount point. Access that directory.
-
Accessing the path triggers the mount.
-
Leaving the path and waiting causes the NFS mount to expire.
-
Accessing it again remounts it.
Finding and Terminating Resource-Intensive Processes¶
For practice purposes, these resource intensive processes will be created manually.
Lab Setup¶
First, a CPU-intensive process needs to be created. This can be a bash script with an infinite while loop.
This will be /usr/local/bin/rhcsa-cpu-hog:
A memory intensive process can be a simple python script.
This will be /usr/local/bin/rhcsa-memory-hog:
#!/usr/bin/python3
import sys
import time
mebibytes = int(sys.argv[1])
memory = bytearray(mebibytes * 1024 * 1024)
# Touch every memory page so it becomes resident in physical memory.
for offset in range(0, len(memory), 4096):
memory[offset] = 1
time.sleep(3600)
Run these scripts with nohup and background the processes.
nohup /usr/local/bin/rhcsa-cpu-hog > /dev/null 2>&1 &
nohup /usr/local/bin/rhcsa-memory-hog > /dev/null 2>&1 &
The task is to identify and terminate these processes without using their names (since we already know the process names for this example).
Solution
Several tools can be used to identify highly resource-intensive processes.
The top and ps commands are the quickest for exam purposes.
-
Use
Look for the processes with the highesttopto identify the processes that are consuming the most CPU and memory.
%CPUand%MEM.-
M(Shift+M): Sort by memory in descending order, highest at the top.
Use the keybindings to sort the processes by memory and CPU usage.
P(Shift+P): Sort by CPU usage in descending order, highest at the top.
-
-
Alternatively, use
pswith--sortto quickly identify the resource intensive processes.-
Identify the memory hog:
-
Identify the CPU hog:
- This may show the
psprocess itself as the highest CPU usage.
- This may show the
-
By default, this will sort in ascending order, with the highest at the bottom.
-
-
Note their PIDs (Process IDs).
-
Use
Replacekillto terminate the processes by their PIDs.
<PID>with the actual PID of the process you want to terminate.-
By default
killsends theSIGTERMsignal (signal 15), which asks the process to terminate gracefully. -
If the process does not terminate with the
SIGTERMsignal, theSIGKILLsignal (signal 9) can be sent to forcefully terminate it.
-
-
Verify that the processes have been terminated by running
topagain or usingps.
Using top is the quickest way to identify the resource-intensive
processes. This is likely the best tool to use when doing things
interactively.
The ps tool can be used in scripts (if automation is needed), or just for
more detailed output.
SELinux Lab: Repair a Custom Apache Document Root¶
This lab is geared towards practicing SELinux and all the different concepts and tools that may be used on the RHCSA exam.
Objectives¶
The objectives are to practice the following.
- Identifying enforcing and permissive modes.
- Temporarily changing the SELinux mode.
- Reading file and process contexts.
- Understanding the SELinux context formats.
- Comparing current and expected SELinux labels.
- Creating persistent file-context rules.
- Applying rules with
restorecon. - Understanding why
chconis normally not a persistent solution. - Verifying that SELinux remains enforcing.
Scenario¶
The web team has moved an apache website from /var/www/html to
/srv/rhcsa-site.
The traditional Linux permissions appear correct and Apache is running, but the
site returns 403 Forbidden.
Diagnose and correct the problem.
Requirements¶
- The website must remain in
/srv/rhcsa-site. - SELinux must be set to
enforcingwhen finished. - The correction must survive
restoreconand a complete filesystem relabel. - Do not solve the problem by permanently making SELinux permissive.
- Do not create a custon SELinux policy module.
RedHat specifically documents /srv as normally using var_t, which Apache
can't read.
The supported correction is a persistent semanage fcontext rule followed by
restorecon.
Lab Setup¶
This section is only for those who wish to build the lab themselves.
If the lab is already set up and must be completed, move on to the next
section.
Lab Setup
Verify SELinux¶
-
Ensure SELinux is enforcing.
If it's anything other than Enforcing, edit the selinux config.
Set the following: -
Reboot the VM before continuing if this was not set.
Install the Required Packages¶
Thehttpd package is Apache, and policycoreutils-python-utils provides
the semanage tool and other SELinux utilities.
Remove any old rule from an earlier lab¶
This might report nothing if the rule doesn't exist.Create the custom document root¶
-
Make the base directory
-
Create the web page.
Add the line:
-
Configure ordinary permissions
-
Ensure that the deliberately incorrect SELinux type is present
Configure Apache¶
-
Create a config file
Add the following configuration -
Check the configuration
This should output
Syntax OK. -
Start/enable Apache.
Verify that the failure exists¶
The response should be: The lab is ready.Assignment¶
Tasks for this lab are as follows.
- Verify the current SELinux mode.
- Verify that Apache is active.
- Verify the website's traditional Linux permissions and ownership.
- Identify the SELinux contexts of the following files:
/srv/srv/rhcsa-site/srv/rhcsa-site/index.html/var/www/html
- Indentify the SELinux domain in which Apache runs.
- Temporarily switch SELinux to permissive mode and test the website.
- Return SELinux to enforcing mode immediately.
- Determine the appropriate SELinux type for static Apache content.
-
Create a persistent file-context rule for
/srv/rhcsa-siteand everything below it. -
Apply the new rule recursively.
- Confirm that Apache can serve the site while SELinux is enforcing.
- Demonstrate that the correction survives an incorrect temporary label.
- Leave Apache running and SELinux enforcing.
Time limit: 25 minutes.
sudo semanage fcontext -a -t httpd_sys_content_t '/srv/rhcsa-site(/.*)?'
restorecon -R /srv/rhcsa-site
LVM Lab¶
This lab covers the current RHEL 10 RHCSA exam objectives involving the following topics:
- GPT partitions
- Creating and removing physical volumes
- Creating and extending volume groups
- Creating and deleting logical volumes
- Creating an XFS filesystem
- Persistent mounting by UUID
- Adding storage non-destructively
- Extending a logical volume and its filesystem
- Creating persistent swap
- Migrating data away from a physical volume
- Removing a physical volume without losing data
- Verifying everything after reboot
Lab Setup¶
Ignore this section if following along during a live session.
Lab Setup
This lab was intended to be set up on a RHEL 10 VM on Proxmox.
The setup simply includes adding 3 virtual disks to the VM, each 4 GiB in
size.
From the Proxmox web UI, go to the VM's "Hardware" tab, click "Add", select
the storage pool to use, and click "Add". Repeat 2 more times.
When finished, run lsblk on the VM to check that the disks were added.
There should be 3 additional disks:
Additionally, ensure that the LVM tools are installed and available for use.
That's all that is required as far as lab setup for this lab.Lab Scenario¶
You administer a RHEL 10 server that requires new storage for project data.
Configure the system to meet these requirements:
- Use the first unused disk to create an LVM physical volume.
- Create a volume group named
vgdata. - Create a 1 GiB logical volume named
lvprojects. - Format
lvprojectswith XFS. - Give the filesystem the label
PROJECTS. - Mount it persistently at
/projectsusing its UUID. - Create a temporary 300 MiB logical volume named
lvtemp. - Delete
lvtempafter verifying it exists. - Add the second unused disk to
vgdata. - Extend
lvprojectsby 1 GiB without losing existing data. - Grow the XFS filesystem to use the additional space.
- Create a 512 MiB logical volume named
lvswap. - Configure it as persistent swap.
- Add the third disk to
vgdata. - Move all allocated extents away from the first physical volume.
- Remove the first physical volume from
vgdata. - Remove its LVM physical-volume label.
- Reboot and verify:
/projectsis mounted.- The existing data is intact.
- The swap logical volume is active.
- The removed physical volume is no longer part of LVM.
Do not delete or modify the operating-system disk.
Solution
This is just a sequence of commands to complete the lab. Explanations may
come at a later point.
sudo pvcreate /dev/sdb
sudo vgcreate vgdata /dev/sdb
sudo lvcreate vgdata -L 1G --name lvprojects
sudo mkfs.xfs -L PROJECTS /dev/mapper/vgdata-lvprojects # steps 4 and 5
# mounting
sudo mkdir -p /projects
sudo vi /etc/fstab
# Add:
# UUID=2c9e5723-835f-41c4-a0bb-d7a49a23aab8 /projects xfs defaults 0 0
sudo lvcreate vgdata -L 300M -n lvtemp
sudo lvs
sudo lvremove vgdata/lvtemp
sudo pvcreate /dev/sdc
sudo vgextend vgdata /dev/sdc
sudo lvextend -L +1G vgdata/lvprojects
sudo xfs_growfs /dev/mapper/vgdata-lvprojects
sudo lvcreate vgdata -L 512M -n lvswap
sudo mkswap /dev/mapper/vgdata-lvswap
sudo vi /etc/fstab
# Add:
# UUID=5d2ef2b0-ff80-4707-b278-12213bbddda0 none swap defaults 0 0
sudo systemctl daemon-reload
sudo swapon -a
sudo swapon --show
# Adding third disk to VG
sudo pvcreate /dev/sdd
sudo vgextend vgdata /dev/sdd
# Move allocated extents away from /dev/sdb
sudo pvmove /dev/sdb
# Remove first PV from VG
sudo vgreduce vgdata /dev/sdb
# Remove PV label
sudo pvremove /dev/sdb
sudo systemctl reboot
When rebooting, it seems that the kernel may relabel the disk that was removed from LVM.
With 3 disks:
/dev/sdb/dev/sdc/dev/sdd
The /dev/sdb disk is removed from LVM during the lab.
After reboot it shows as still part of LVM, and /dev/sdc is now the disk that
was removed.
This is likely due to the kernel relabeling the disks.