0% found this document useful (0 votes)
20 views93 pages

Github

The document outlines a practice exam for the RHCSA-EX200 certification, detailing 18 questions that require configuring two RHEL 8 virtual machines. It includes specific tasks such as setting up hostnames, configuring YUM repositories, debugging SELinux, creating user accounts, and setting up services like NTP and autofs. Each question is accompanied by step-by-step answers to guide the user through the necessary configurations.

Uploaded by

orange
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views93 pages

Github

The document outlines a practice exam for the RHCSA-EX200 certification, detailing 18 questions that require configuring two RHEL 8 virtual machines. It includes specific tasks such as setting up hostnames, configuring YUM repositories, debugging SELinux, creating user accounts, and setting up services like NTP and autofs. Each question is accompanied by step-by-step answers to guide the user through the necessary configurations.

Uploaded by

orange
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

[Link]

com/RedHatRanger/rhcsa9vagrant/blob/main/rhcsa-
practice-questions/bonus_labs/vdo_on_lvm.md

Practice Exam for RHCSA-EX200


This is a sample of RHCSA-EX200 exam that I’ve created to prepare for my
exam. As with the real exam, no perfect answers to the sample exam
questions will be provided, but more or less correct and accurate.
Remember you want to cover all topics first before start dealing with
questions.

Requirements
There are 18 questions in total could be more or less. You will be given 2
RHEL 8 virtual machines which you need to configure properly to be able
to successfully complete all questions and pass the exam.

One VM will be configured as an Server-A and another would be Server-B.


there will be a repository VM which will enable you to install packages to
your VMs. The following FQDNs will be used throughout the sample exam.

FQDN Description IP Addresses Network mask

[Link]
node1 [Link] [Link]
m

[Link]
node2 [Link] [Link]
m

Lab Setup
you can create the lab setup manually, but instead i've Vagrantfile which
you can use inorder to create this setup, please go to this website for
more information regarding lab
setup [Link]

Question:1 Configure your Host Name, IP


Address, Gateway and DNS.
Configure your Host Name, IP Address, Gateway and DNS.

 Host name: [Link]


 IP Address: [Link]/24
 Network Mask: [Link]
 Gateway: [Link]
 DNS: [Link]

Answer:1 Configure your Host Name, IP


Address, Gateway and DNS.
setting up hostname
[root@Server-A ~]# vim /etc/hostname

or

[root@Server-A ~]# hostnamectl set-hostname <hostname>

setting ipv4/GW/DNS
[root@Server-A ~]# nmcli connection modify enp0s3 autoconnect yes
[Link] manual [Link] [Link] [Link]
[Link] [Link] [Link]

or

[root@Server-A ~]# vim /etc/sysconfig/network-scripts/ifcfg-enp0s3


IPADDR=[Link]
GATEWAY=[Link]
DNS1=[Link]

Question:2 Configure your system to use


the default repository
YUM repositories are already available from

 [Link]
 [Link]
 Configure your system to use these locations as default repository

Answer:2 Configure your system to use the


default repository
1. Install the yum-config-manager installation package

[root@clear ~]# rpm -ivh


[Link]
[Link]

2. repository file download and install

# yum-config-manager command could be helpful to set a local repository


quickly
# yum-config-manager -h command to look for some help
[root@clear ~]# yum-config-manager --add-repo
[Link]
Adding repo from: [Link]

[root@clear ~]# yum-config-manager --add-repo


[Link]
Adding repo from: [Link]

3. Check if the installation is successful

[root@clear ~]# cd /etc/[Link].d/


[root@clear [Link].d]# ls
[Link].com_dvd_AppStream.repo
[Link].com_dvd_BaseOS.repo

4. you should also ensure some parameters are correct

[root@clear [Link].d]# vim [Link].com_dvd_BaseOS.repo


# enabled=1
# gpgcheck=0

Question:3 Debug SELinux (service)


A web server running on a non-standard port 82 is having trouble serving
content. Debug and resolve the issue as necessary so that the following
conditions are met:

 The web server on the system is able to serve all existing HTML files
in /var/www/html (note: do not delete or otherwise alter the contents
of existing files)

 The web server serves this content on port 82

 The web server starts automatically at system startup

Answer:3 Debug SELinux (service)


 semanage command is used to query and modify the security
context of the SELinux default directory

 apache belongs to httpd service

1. View httpd service status

[root@node1 ~]# systemctl status httpd


Active: failed (Result: exit-code)

2. View the security context of the HTML file

ls -Z #prints the security context of the file

[root@node1 html]# ls -Z /var/www/html/*


system_u:object_r:default_t:s0 /var/www/html/file1
system_u:object_r:httpd_sys_content_t:s0 /var/www/html/file2
system_u:object_r:httpd_sys_content_t:s0 /var/www/html/file3

3. Modify the security context of the original /var/www/html/file1 file

man semange fcontext


# parameters to look for -a is replaced by -m (modify)

[root@node1 html]# semanage fcontext -m -t httpd_sys_content_t


"/var/www/html/file1"

4. Refresh the security context

[root@node1 html]# restorecon -R -v /var/www/html/file1


Relabeled /var/www/html/file1 from system_u:object_r:default_t:s0 to
system_u:object_r:httpd_sys_content_t:s0

5. Use semanage to release port 82

# man semanage port


[root@node1 ~]# semanage port -a -t http_port_t -p tcp 82

6. Check whether port 82 is allowed

# man semanage port


[root@node1 ~]# semanage port -l | grep http
http_port_t tcp 82, 80, 81, 443, 488, 8008, 8009, 8443, 9000

7. Restart the httpd service, set the boot to start automatically, and
check whether the service is enabled

[root@node1 ~]# systemctl restart httpd


[root@node1 ~]# systemctl enable httpd
[root@node1 ~]# systemctl status httpd

8. Access verification

[root@node1 html]# curl [Link]

Question:4 create user account


Create the following users, groups, and group memberships: A group
named sysmgrs

 User natasha , who also belongs to sysmgrs as a secondary group


 User harry , who also belongs to sysmgrs as a secondary group
 User sarah , does not have access to an interactive shell on the
system and is not a member of sysmgrs
 passwords for natasha , harry and sarah should all be password
Answer:4 create user account
[root@clear ~]# groupadd sysmgrs
[root@clear ~]# useradd natasha -G sysmgrs
[root@clear ~]# useradd harry -G sysmgrs
[root@clear ~]# useradd sarah --shell /sbin/nologin
[root@clear ~]# echo "password" | passwd --stdin natasha
Changing password for user natasha.
passwd: all authentication tokens updated successfully.
[root@clear ~]# echo "password" | passwd --stdin harry
Changing password for user harry.
passwd: all authentication tokens updated successfully.
[root@clear ~]# echo "password" | passwd --stdin sarah
Changing password for user sarah.
passwd: all authentication tokens updated successfully.

Check connectivity
[root@node1 ~]# ssh natasha@localhost
[harry@node1 ~]$ ssh sarah@localhost
[harry@node1 ~]$ ssh sarah@localhost #no interactive shell allocated for
sarah /sbin/nologin

Question:5 Configure a cron job (service)


Configure a cron job that runs every 2 minutes and executes the following
command:

 logger "EX200 in progress", run as user natasha

Answer:5 Configure a cron job (service)


[Link] if cron service is currently running
[root@node1 ~]# systemctl status [Link]
Active: active (running)

2. Edit scheduled tasks


[root@node1 ~]# crontab -u natasha -e
[root@node1 ~]# crontab -u natasha -l
*/2 * * * * logger "EX200 in progress"

3. enable and restart service


[root@node1 ~]# systemctl enable [Link]

[Link] if log message are being loggged


#verify
[root@node1 ~]# grep EX200 /var/log/messages
node1 natasha[28082]: EX200 in progress
node1 natasha[28086]: EX200 in progress
node1 natasha[28097]: EX200 in progress

Question:6 Create a collaboration directory


 /home/managers with the following characteristics:
 The group permissions for /home/managers are sysmgrs.
 The directory should be read, write, and accessible by members of
sysmgrs, but not by any other user. (Of course, the root user has
access to all files and directories on the system).
 Files created in /home/managers automatically set group ownership to
the sysmgrs group.

Answer:6 Create a collaboration directory


Check if directory exists
[root@node1 ~]# ll -d /home/managers

1. Create the specified directory file


[root@node1 ~]# mkdir /home/managers

[Link] the group permission of `/home/managers` to sysmgrs

[root@node1 ~]# ll -d /home/managers/


drwxr-xr-x. 2 root root 6 May 14 18:16 /home/managers/

[root@node1 ~]# chown root:sysmgrs /home/managers/

[root@node1 ~]# ll -d /home/managers/


drwxr-xr-x. 2 root sysmgrs 6 May 14 18:16 /home/managers/

3. Modify the directory file and the permissions of the group to which it
belongs
[root@node1 ~]# chmod 070 /home/managers/
[root@node1 ~]# chmod g=rwx,o=- /home/managers

[root@node1 ~]# ll -d /home/managers/


d---rwx---. 2 root sysmgrs 6 May 14 18:16 /home/managers/

4. Set special permissions for the `/home/managers` directory so that its


subdirectories inherit the group of the parent directory
[root@node1 ~]# chmod g+s /home/managers/

[root@node1 ~]# ll -d /home/managers/


d---rws---. 2 root sysmgrs 6 May 14 18:16 /home/managers/

5. Verify the effect of g+s permission


[root@node1 managers]# touch file
[root@node1 managers]# ll
total 0
-rw-r--r--. 1 root sysmgrs 0 May 14 18:27 file

Question:7 Configure NTP (time


synchronization service) (service)
 Configure your system to be an NTP client for [Link].
(Note: [Link] is a DNS alias for
[Link])
Answer:7 Configure NTP (time
synchronization service) (service)
# systemctl list-units lists all startup units
# Unit is the basic unit for Systemd to manage system resources

# The client side synchronizes with the server


# nodel is the client [Link]'s NTP is the server

[Link] the name of the main configuration file of the NTP service
[root@node1 ~]# systemctl list-units | grep NTP
[Link]

2. Confirm whether the service is started


[root@node1 ~]# systemctl status [Link]
Active: active (running)

3. Modify the service configuration file and specify the address of the
upstream server to be added
[root@node1 ~]# vim /etc/[Link]
#server_gateway iburst
server [Link] iburst

4. Restart the service, let the modification of the configuration file take
effect, and set the boot to start automatically
[root@node1 ~]# systemctl restart [Link]
[root@node1 ~]# systemctl enable [Link]

5. Verify
method one:
[root@node1 ~]# chronyc sources -v #View synchronization time status
^* [Link]

method two:
[root@node1 ~]# timedatectl
#Check whether NTP is active and whether the system clock is synchronized
System clock synchronized: yes
NTP service: active

Question:8 Configure autofs (service)


 Configure autofs to automatically mount remote users' home
directories as follows:

 [Link] ( [Link] ) NFS exports /rhome to


your system. This file system contains a preconfigured home
directory for - user remoteuser1
 remoteuser1's home directory
is [Link]:/rhome/remoteuser1
 The home directory of remoteuser1 should be automatically
mounted to /rhome/remoteuser1 under the local /rhome

 The home directory must be writable by its user


 The password for remoteuser1 is password

Answer:8 Configure autofs (service)


1. Find the main configuration file
[root@node1 ~]# rpm -qc autofs
/etc/[Link] # absolute path configuration file
/etc/[Link] # relative path configuration file

2. Configure the main configuration file


[root@node1 ~]# vim /etc/[Link]
/misc /etc/[Link]
/rhome /etc/[Link] #relative path configuration file

3. Copy the relative path configuration file to the path written by the
main configuration file
[root@node1 ~]# cp /etc/[Link] /etc/[Link]

4. Edit the relative path configuration file


[root@node1 ~]# vim /etc/[Link]
remoteuser1 -rw [Link]:/rhome/remoteuser1

5. restart service
[root@node1 ~]# systemctl restart [Link]

check status
[root@node1 ~]# systemctl status [Link]
Active: active (running)

Set up autostart
[root@node1 ~]# systemctl enable [Link]
Created symlink /etc/systemd/system/[Link]/[Link]
→ /usr/lib/systemd/system/[Link].

6. Login test
[root@node1 ~]# ssh remoteuser1@localhost
[remoteuser1@clear ~]$ pwd
/rhome/remoteuser1
Check write permissions
[remoteuser1@node1 ~]$ touch [Link]
[remoteuser1@node1 ~]$ ll
total 0
-rw-rw-r--. 1 devops devops 0 May 27 12:04 [Link]

Question:9 Configure /var/tmp/fstab


permissions
 Copy the file /etc/fstab to /var/tmp/fstab . Configure the permissions
of /var/tmp/fstab to meet the following conditions:
 File /var/tmp/fstab owned by root user
 File /var/tmp/fstab belongs to group root
 The file /var/tmp/fstab should not be executable by anyone.
 User natasha can read and write to /var/tmp/fstab.
 User harry cannot write or read /var/tmp/fstab.
 All other users (current or future) can read /var/tmp/fstab.

Answer:9 Configure /var/tmp/fstab


permissions
1. File copy
[root@node1 ~]# cp /etc/fstab /var/tmp/fstab

2. Check whether the owner and the owner group meet the meaning of the
question, and there is no execution permission
[root@node1 ~]# ll -d /var/tmp/fstab
-rw-r--r--. 1 root root 534 May 23 12:27 /var/tmp/fstab

3. Set setfacl permission


man setfacl
[root@node1 ~]# setfacl -m u:natasha:rw-,u:harry:- /var/tmp/fstab

4. Verify
[root@node1 ~]# getfacl /var/tmp/fstab
user:natasha:rw-
user:harry:---

Question:10 Configure user accounts


 Configure user manalo with user ID 3533.

Answer:10 Configure user accounts


[root@clear ~]# useradd -u 3533 manalo
[root@clear ~]# echo "password" | passwd --stdin manalo
Changing password for user manalo.
passwd: all authentication tokens updated successfully.

Question:11 Find files


 Find all files owned by jacques and place a copy of them in
the /root/findfiles directory.

Answer:11 Find files


1. Create a directory
[root@clear ~]# mkdir /root/findfiles

2. Find
[root@clear ~]# find / -user jacques -exec cp -a {} /root/findfiles/ \;

3. Verification
[root@clear ~]# ls /root/findfiles/
gamelan jacques [Link].1.2.3
Question:12 Find a string
 Finds all lines in the file /usr/share/xml/iso-codes/iso_639_3.xml that
contain the string ng.
 Put a copy of all these lines in the file /root/list in their original
order.
 /root/list must not contain empty lines, and all lines must be exact
copies of the original lines in /usr/share/xml/iso-codes/iso_639_3.xml.

Answer:12 Find a string


1. Find the string
[root@node1 ~]# grep ng /usr/share/xml/iso-codes/iso_639_3.xml | grep -v ^$
> /root/list

2. Verification
[root@node1 ~]# cat -n /root/list

Question:13 Create archive


 Create a tar archive named /root/[Link], which should
contain the tar archive of /usr/local
 Which should contain the contents of /usr/local. The tar archive
must be compressed with gzip format.

Answer:13 Create archive


1. pack
[root@clear ~]# tar -czvf /root/[Link] /usr/local

2. Verification
[root@clear ~]# ls
[Link] findfiles
[Link] [Link]

3. Verify whether it is gzip


[root@clear ~]# file [Link]
[Link]: gzip compressed data, last modified: Sun May 22 17:10:03 ,
from Unix, original size 51200

Question:14 Add a swap partition


Adding an extra 512M swap partition to your system, this swap partition
should mount automatically when the system starts up. Don't remove and
modify the existing swap partitions on your system.

Answer:14 Add a swap partition


1. List all block devices
[root@node2~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 252:0 0 10G 0 disk
├─vda1 252:1 0 1M 0 part
├─vda2 252:2 0 100M 0 part /boot/efi
└─vda3 252:3 0 9.9G 0 part /
vdb 252:16 0 4G 0 disk
├─vdb1 252:17 0 510M 0 part
│ └─myvol-vo 253:1 0 232M 0 lvm /reports
└─vdb2 252:18 0 512M 0 part
└─vgroup-swap 253:0 0 256M 0 lvm [SWAP]
vdc 252:32 0 10G 0 disk

2. Create disk partitions


[root@node2 ~]# fdisk /dev/vdb

3. Formatting
[root@node2 ~]# mkswap /dev/vdb3
Setting up swapspace version 1, size = 512 MiB (792719360 bytes)
no label, UUID=ba522efa-8aa3-4e96-b8e2-39aafa20f3cb

4. Permanent mount
[root@node2 ~]# vim /etc/fstab
UUID=ba522efa-8aa3-4e96-b8e2-39aafa20f3cb none swap defaults 0 0

5. Verify
[root@node2 ~]# swapon -a #refresh
[root@node2 ~]# swapon
NAME TYPE SIZE USED PRIO
/dev/dm-0 partition 256M 0B -2
/dev/vdb3 partition 512M 0B -3

Question:15 Create a logical volume


Create a new logical volume as required:

 Name the logical volume as database, belongs to datastore of the


volume group, size is 60 PE.
 Expansion size of each volume in volume group datastore is 16MB.
 Use ext3 to format this new logical volume, this logical volume
should automatically mount to /mnt/database.

Answer:15 Create a logical volume


1. Create a disk partition
[root@node2 ~]# fdisk /dev/vdb

2. Create a physical group (pv)


[root@node2 ~]# pvcreate /dev/vdb4
Physical volume "/dev/vdb4" successfully created.

3. Create a volume group (vg)


[root@node2 ~]# vgcreate qagroup -s 16M /dev/vdb4
# -s Extended block (PE) size of the physical volume on the volume group
Volume group "qagroup" successfully created
4. Create a logical volume (lv)
[root@node2 ~]# lvcreate -n qa -l 60 /dev/qagroup
Logical volume "qa" created.

5. Formatting
[root@node2 ~]# mkfs.ext3 /dev/qagroup/qa

6. View UUID
[root@node2 ~]# blkid /dev/qagroup/qa
/dev/qagroup/qa: UUID="5ad7f2df-9749-4a46-adb6-853f3805d795"
SEC_TYPE="ext2" TYPE="ext3"

7. Create /mnt/qa directory


[root@node2 ~]# mkdir /mnt/qa

8. Make a permanent mount


[root@node2 ~]# vim /etc/fstab
UUID="5ad7f2df-9749-4a46-adb6-853f3805d795" /mnt/qa ext3 defaults 0 0

9. load
[root@node2 ~]# mount -a # Load all devices set in the file /etc/fstab

10.
[root@node2 ~]# df -h
/dev/mapper/qagroup-qa 929M 1.2M 880M 1% /mnt/qa

Question:16 Create a logical volume


 Set logical volume size

 Resize the logical volume vo and its file system to 230 MiB. Make
sure the filesystem contents remain unchanged. Note: The partition
size is rarely exactly the requested size, so a range of 230 MiB to 270
MiB is acceptable.

Answer:16 Create a logical volume


1. Query logical volume vo
[root@node2 ~]# df -h
/dev/mapper/myvol-vo 175M 1.6M 160M 1% /reports

2. Expansion
[root@node2 ~]# lvextend -L 250M /dev/mapper/myvol-vo #Expand logical
volume space
Logical volume myvol/vo successfully resized.

3. Query formatting type (ext4)


[root@node2 ~]# blkid | grep vo
/dev/mapper/myvol-vo: UUID="67994f68-d3e1-4686-8393-8df05149883f"
TYPE="ext4"

5. Refresh according to type


[root@node2 ~]# resize2fs /dev/mapper/myvol-vo
6. Verify
[root@node2 ~]# df -h
/dev/mapper/myvol-vo 240M 2.1M 204M 1% /reports

Question:17 Permissions
1. Find all sizes of 10k file or directory under the /etc directory, and
copy to /tmp/findfiles directory.
2. Find all the files or directories with Lucy as the owner, and copy
to /tmp/findfiles directory.

Answer:17 Permissions
1. File copy
[root@node1 ~]# cp /etc/fstab /var/tmp/fstab

2. Check whether the owner and the owner group meet the meaning of the
question, and there is no execution permission
[root@node1 ~]# ll -d /var/tmp/fstab
-rw-r--r--. 1 root root 534 May 23 12:27 /var/tmp/fstab

3. Set setfacl permission


man setfacl
[root@node1 ~]# setfacl -m u:natasha:rw-,u:harry:- /var/tmp/fstab

4. Verify
[root@node1 ~]# getfacl /var/tmp/fstab
user:natasha:rw-
user:harry:---

Question:20 Create a script for locating


files
 Create a script named /usr/local/bin/[Link].
 Find all files under /usr that are less than 10M and
have sgid permissions set.
 Save the found file list to /root/myfile.

Answer:20 Create a script for locating files


[root@servera ~]# vim /usr/local/bin/[Link]
#!/bin/bash
find /usr -size -10M -perm -2000 > /root/myfile
[root@servera ~]# chmod a+x /usr/local/bin/[Link]
[root@servera ~]# [Link]
[root@servera ~]# cat /root/myfile
/usr/bin/write
/usr/bin/locate
/usr/libexec/utempter/utempter
/usr/libexec/openssh/ssh-keysign
Question:21 Creating scripts
 Create a newsearchscript called
 The script is placed /usr/binunder
 This script is used to find /usrall files that are greater than 30k, but
less than 50k and have SUIDpermissions, and place these file names
in the /root/newfilesfile

Answer:21 Creating scripts


# vim /usr/bin/newsearch

#!/bin/bash
touch /root/newfiles
find /usr -size +30k -size -50k -perm /u=s > /root/newfiles

# chmod +x /usr/bin/newsearch

# ./usr/bin/newsearch

# cat /root/newfiles

Question:22 Creating scripts


create script

 Create a myresearchscript called


 The script is placed /usr/binunder
 This script is used to find /usrall files that are smaller than 10m and
have modification Group ID permissions s, and place these
files /root/myfilesunder

Answers:22 Creating scripts


# vim /usr/bin/newsearch

#!/bin/bash
mkdir /root/newfiles
find /usr -size -10M -perm /u=s cp -a {} /root/newfiles \;

# chmod +x /usr/bin/newsearch

# ./usr/bin/newsearch

# cat /root/newfiles

Solutions to Ordered Task List


This guide shows all of the steps I took for completing each task while
preparing for the exam.
1. Break into server2 and set the password as password. Set the target as
multi-user and make sure it boots into that automatically. Reboot to
confirm.

Solution to Task 1

### While booting into server2, when the GRUB menu screen appears, press
the "down" arrow
### to select the rescue kernel, and then press `e` to enter edit mode.

### Append to the end of the line beginning with `linux`


[Link]=[Link] [Link] enforcing=0

### Ctrl-x to boot into rescue mode


### Enter
mount -o rw,remount /sysroot
chroot /sysroot
passwd root
### password twice
### Ctrl-d twice (just hold ctrl and tap d twice) to fully boot

### Login
restorecon /etc/shadow
systemctl set-default multi-user
systemctl reboot
2. Configure the network interfaces and hostnames on both servers.

Solution to Task 2

### On server1:
nmcli con show

### Output shows `enp0s8` as unconfigured


nmcli con mod enp0s8 [Link] manual [Link] "[Link]/24"
[Link] "[Link]" [Link] "[Link]" [Link] manual
[Link] "2002:fe60:def0::55/64"
nmcli con down enp0s8
nmcli con up enp0s8
nmcli general hostname rhcsa9-server1

### Check to make sure everything is good


nmcli con show enp0s8

### On server2:
nmcli con show

### Output shows `enp0s8` as unconfigured


nmcli con mod enp0s8 [Link] manual [Link] "[Link]/24"
[Link] "[Link]" [Link] "[Link]" [Link] manual
[Link] "2002:fe60:def0::56/64"
nmcli con down enp0s8
nmcli con up enp0s8
nmcli general hostname rhcsa9-server1

### Check to make sure everything is good


nmcli con show enp0s8
3. Ensure network services start at boot.
Solution to Task 3

systemctl status NetworkManager

### Check to see that it's enabled and running. If not, then run
systemctl enable --now NetworkManager
4. Enable ssh access for root on both servers.

Solution to Task 4

vi /etc/ssh/sshd_config

### Change the following line (should be line 40):


PermitRootLogin yes

systemctl restart sshd


5. Enable key-based ssh authentication for root on both servers.

Solution to Task 5

### On server1:
ssh-keygen
ssh-copy-id root@[Link]
scp /root/.ssh/* root@[Link]:/root/.ssh

### On server2:
ssh-copy-id root@[Link]
6. Configure the repos on server1.

Solution to Task 6

### On server1:
vi /etc/[Link].d/[Link]

### Add the below contents to the file:


[BaseOS]
name=BaseOS
enabled=1
baseurl=[Link]
gpgcheck=0

[AppStream]
name=AppStream
enabled=1
baseurl=[Link]
gpgcheck=0

[F37]
name=Fedora 37
enabled=0
baseurl=[Link]
37/Everything/x86_64/os/
gpgcheck=0
7. Secure copy the repo file to server2.
Solution to Task 7

### On server1:
scp /etc/[Link].d/[Link] root@[Link]:/etc/[Link].d/
8. Configure autofs to automatically mount individual users' home
directories from /export/home on [Link]
to /mnt/autofs_home/<user_name>.

Solution to Task 8

### On both servers:


dnf install -y nfs-utils autofs
systemctl enable --now autofs
mkdir /mnt/autofs_home

### Add the following line to /etc/[Link]:


/mnt/autofs_home /etc/[Link]

### Create and add the following to /etc/[Link]:


* [Link]:/export/home/&

systemctl restart autofs


9. Configure both servers to create files with 660 permissions by default.

Solution to Task 4

### On both servers:


vi /etc/[Link]

### Change the following line (should be line 117):


UMASK 007
10. Set password policies to require a minimum of 8 characters and a
maximum age of 60 days.

Solution to Task 10

### On both servers:


vi /etc/[Link]

### Change the following line (should be line 131)


PASS_MAX_DAYS 60

vi /etc/security/[Link]

### Uncomment or change the following line (should be line 11):


minlen = 8
11. Write shell scripts on server1 that create users and groups according
to the following parameters. Ensure all users except cindy use autofs for
their profiles:

manny:1010:dba_admin,dba_managers,dba_staff
moe:1011:dba_admin,dba_staff
jack:1012:dba_intern,dba_staff
marcia:1013:it_staff,it_managers
jan:1014:dba_admin,dba_staff
cindy:1015:dba_intern,dba_staff

Solution to Task 11

On server1, create a text file called "[Link]" that contains the


following:

dba_admin:5010
dba_managers:5011
dba_staff:5012
dba_intern:5013
it_staff:5014
it_managers:5015
Then create a shell script called "[Link]" that contains the
following:
Note: "IFS" is internal field separator, and will separate the group names
from the group IDs.

#!/bin/bash

while IFS=":" read group gid ; do


echo "Creating group $group..."
groupadd -g $gid $group
done < [Link]
Set the permissions on the file so it's executable, then run it:

chmod +x [Link]
./[Link]
Now check that the groups were created:

egrep "it|dba" /etc/group


Now that the groups are created, create a text file called "[Link]" that
contains the following:
Note: Remember that "cindy" is being created differently, so needs to be
omitted.

manny:1010:dba_admin,dba_managers,dba_staff
moe:1011:dba_admin,dba_staff
jack:1012:dba_intern,dba_staff
marcia:1013:it_staff,it_managers
jan:1014:dba_admin,dba_staff
Create a shell script called "[Link]" that contains the following:
Note: Here we still use the IFS, and we specify the home path with -b, the
auxilary groups with -G and not to create a home directory with -M.
#!/bin/bash

while IFS=":" read user uid group ; do


echo "Creating user $user..."
useradd -b /mnt/autofs_home -G $group -u $uid -M $user
done < [Link]
Set the permissions on the file so it's executable, then run it:

chmod +x [Link]
./[Link]
Check to make sure the users were created and added to the appropriate
groups:

tail /etc/passwd
egrep "it|dba" /etc/group
Finally, create "cindy" as a one-off user with a local profile:

useradd -u 1015 -G dba_intern,dba_staff cindy


12. Secure copy the shell scripts to server2 and perform the same
functions.

Solution to Task 12

scp create* root@[Link]:/root/


scp *.txt root@[Link]:/root/

### Now on server2:


./[Link]
./[Link]
useradd -u 1015 -G dba_intern,dba_staff cindy
13. Set the password on all of the newly created users to dbapass.

Solution to Task 13

### On both servers:

for user in manny moe jack marcia jan cindy; do echo "dbapass" | passwd --
stdin $user; done
14. Create sudo command alias for MESSAGES with the command /bin/tail
-f /var/log/messages

Solution to Task 14

### On both servers:

visudo

### While in visudo, add the following lines:

## Messages
Cmnd_Alias MESSAGES = /bin/tail -f /var/log/messages
15. Enable superuser privileges according to the following:

dba_managers: everything
dba_admin: SOFTWARE, SERVICES, PROCESSES
dba_intern: MESSAGES

Solution to Task 15

### On both servers:

visudo

### While in visudo, uncomment the following lines:


Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum
Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl
start....
Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill,
/usr/bin/killall

### Then add the following to the mapping section, after %wheel%:

%dba_managers ALL=(ALL) ALL


%dba_admin ALL = SOFTWARE, SERVICES, PROCESSES
%dba_intern ALL = MESSAGES
16. Switch to the various users using su and test their privileges.

Solution to Task 16

### manny is a dba_manager, so he should have all rights:


su - manny
sudo -i
### If he can elevate, it works

### moe is a dba_admin, but not a dba_manager:


su - moe
sudo -i (this should fail)
sudo yum install tree (don't confirm, but this should work)

### jack is a dba_intern, but not a dba_admin or dba_manager:


su - jack
sudo -i (this should fail)
sudo yum install tree (this should fail)
sudo tail -f /var/log/messages

### marcia is not a member of any elevated groups:


su - marcia
sudo -i (this should fail)
sudo yum install tree (this should fail)
sudo tail -f /var/log/messages (this should fail)
17. On server1 create a tar w/gzip archive of /etc called etc_archive.[Link]
in the /archives directory.

Solution to Task 17

dnf install -y tar gzip


tar -czvf /archives/etc_archive.[Link] /etc
18. On server1 create a star w/bzip2 archive of /usr/share/doc called
doc_archive.star.bz2 in the /archives directory.

Solution to Task 18

dnf install -y star --repo F37


dnf install -y bzip2
star -c -v -j file=/archives/doc_archive.star.bz2 /usr/share/doc
19. On server1 create a folder called /links, and under links create a file
called file01. Create a soft link called file02 pointing to file01, and a hard
link called file03 pointing to file01. Check your work.
Solution to Task 19

mkdir /links
touch /links/file01
ln -s /links/file01 /links/file02
ln /links/file01 /links/file03
ls -lai /links
20. Find all setuid files on server1 and save the list to /root/[Link].

Solution to Task 20

find / -type f -perm -u+s > /root/[Link]


cat [Link]
21. Find all files larger than 3MB in the /etc directory on server1 and copy
them to /largefiles.

Solution to Task 21

mkdir /largefiles
find /etc -type f -size +3M -exec cp {} /largefiles \; 2>/dev/null
ls -al /largefiles/
22. On both servers persistently mount /export/dba_files from the server
[Link] under /mnt/dba_files. Ensure manny is the user owner and
dba_staff is the group owner. Ensure the groupID is applied to newly
created files. Ensure users can only delete files they have created. Ensure
only members of the dba_staff group can access the directory.

Solution to Task 22

mkdir /mnt/dba_files
vi /etc/fstab

### Add the following line to /etc/fstab:


[Link]:/export/dba_files /mnt/dba_files nfs defaults 0 0

### Write and quit /etc/fstab, then check the mount:


mount -a

### Set the permissions:


chown manny:dba_staff /mnt/dba_files
chmod 770 /mnt/dba_files
chmod g+s,+t /mnt/dba_files
23. On both servers persistently mount /export/it_files from the server
[Link] under /mnt/it_files. Ensure marcia is the user owner and
it_staff is the group owner. Ensure the groupID is applied to newly created
files. Ensure users can only delete files they have created. Ensure only
members of the it_staff group can access the directory.

Solution to Task 23

mkdir /mnt/it_files
vi /etc/fstab
### Add the following line to /etc/fstab:
[Link]:/export/it_files /mnt/it_files nfs defaults 0 0

### Write and quit /etc/fstab, then check the mount:


mount -a

### Set the permissions:


chown marcia:it_staff /mnt/it_files
chmod 770 /mnt/it_files
chmod g+s,+t /mnt/it_files
24. Create a job using at to write "This task was easy!" to
/coolfiles/at_job.txt in 10 minutes.

Solution to Task 24

dnf install -y at
systemctl enable --now atd

at now + 10 minutes
mkdir /coolfiles
echo "This task was easy!" > /coolfiles/at_job.txt
#Ctrl-d to exit
25. Create a job using cron to write "Wow! I'm going to pass this test!"
every Tuesday at 3pm to /var/log/messages.

Solution to Task 25

vi /etc/crontab

### Add the following line to /etc/crontab


0 15 * * 2 root echo "Wow! I'm going to pass this test!" >>
/var/log/messages
26. Write a script named [Link] in the root directory on server1.

 a) If “me” is given as an argument, then the script should output “Yes, I’m
awesome.”
 b) If “them” is given as an argument, then the script should output “Okay,
they are awesome.”
 c) If the argument is empty or anything else is given, the script should
output “Usage ./[Link] me|them”

Solution to Task 26

vi /[Link]
Add the following to the file:

#!/bin/bash

if [ "$1" = "me" ] ; then


echo "Yes, I'm awesome."

elif [ "$1" = "them" ] ; then


echo "Okay, they are awesome."

else
echo "Usage ./[Link] me|them"

fi
Change the permissions and test it:

chmod +x /[Link]
/[Link] me
/[Link] them
/[Link] everyone
/[Link]
27. Fix the web server on server1 and make sure all files are accessible.
Do not make any changes to the web server configuration files. Ensure it's
accessible from server2 and the client browser.

Solution to Task 27

Ok, this is a long one. First, we need to check the web server and see
what's going on:

systemctl status httpd


We see something similar to the following:

× [Link] - The Apache HTTP Server


Loaded: loaded (/usr/lib/systemd/system/[Link]; enabled; vendor
preset: disabled)
Active: failed (Result: exit-code) since Wed 2023-02-08 14:03:47 CET;
7s ago
Docs: man:[Link](8)
Process: 2935 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
(code=exited, status=1/FAILURE)
Main PID: 2935 (code=exited, status=1/FAILURE)
Status: "Reading configuration..."
CPU: 37ms

Feb 08 14:03:47 rhcsa9-server1 systemd[1]: Starting The Apache HTTP


Server...
Feb 08 14:03:47 rhcsa9-server1 httpd[2935]: AH00558: httpd: Could not
reliably determine the server's fully qualified domain name, using
fe80::a00:2>
Feb 08 14:03:47 rhcsa9-server1 httpd[2935]: (13)Permission denied: AH00072:
make_sock: could not bind to address [::]:85
Feb 08 14:03:47 rhcsa9-server1 httpd[2935]: (13)Permission denied: AH00072:
make_sock: could not bind to address [Link]:85
Feb 08 14:03:47 rhcsa9-server1 httpd[2935]: no listening sockets available,
shutting down
Feb 08 14:03:47 rhcsa9-server1 httpd[2935]: AH00015: Unable to open logs
Feb 08 14:03:47 rhcsa9-server1 systemd[1]: [Link]: Main process
exited, code=exited, status=1/FAILURE
Feb 08 14:03:47 rhcsa9-server1 systemd[1]: [Link]: Failed with
result 'exit-code'.
Feb 08 14:03:47 rhcsa9-server1 systemd[1]: Failed to start The Apache HTTP
Server.
Ok, we can see here that the it had (13)Permission denied, and could not
bind to port 85. So, we know the webserver is on port 85, and it's having a
permissions issue. Port 85 is a reserved port, and SELinux isn't going to let
us bind to that port. Let's get some tools installed to troubleshoot:
dnf install -y policycore* setrouble*
Now that we have our tools installed, let's try to start it again and see
what our logs tell us:

systemctl start httpd


grep httpd /var/log/messages
Oh man, look at all that gold...

Feb 8 14:03:47 rhcsa9-server1 httpd[2935]: AH00558: httpd: Could not


reliably determine the server's fully qualified domain name, using
fe80::a00:27ff:fe6b:9f4a%enp0s3. Set the 'ServerName' directive globally to
suppress this message
Feb 8 14:03:47 rhcsa9-server1 httpd[2935]: (13)Permission denied: AH00072:
make_sock: could not bind to address [::]:85
Feb 8 14:03:47 rhcsa9-server1 httpd[2935]: (13)Permission denied: AH00072:
make_sock: could not bind to address [Link]:85
Feb 8 14:03:47 rhcsa9-server1 httpd[2935]: no listening sockets available,
shutting down
Feb 8 14:03:47 rhcsa9-server1 httpd[2935]: AH00015: Unable to open logs
Feb 8 14:03:47 rhcsa9-server1 systemd[1]: [Link]: Main process
exited, code=exited, status=1/FAILURE
Feb 8 14:03:47 rhcsa9-server1 systemd[1]: [Link]: Failed with
result 'exit-code'.
Feb 8 14:03:50 rhcsa9-server1 setroubleshoot[2936]: SELinux is
preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 85.
For complete SELinux messages run: sealert -l d28fbbf2-b7c7-4a6d-a677-
7b498dc14c8c
Feb 8 14:03:50 rhcsa9-server1 setroubleshoot[2936]: SELinux is
preventing /usr/sbin/httpd from name_bind access on the tcp_socket port
85.#012#012***** Plugin bind_ports (99.5 confidence) suggests
************************#012#012If you want to allow /usr/sbin/httpd to
bind to network port 85#012Then you need to modify the port
type.#012Do#012# semanage port -a -t PORT_TYPE -p tcp 85#012 where
PORT_TYPE is one of the following: http_cache_port_t, http_port_t,
jboss_management_port_t, jboss_messaging_port_t, ntop_port_t,
puppet_port_t.#012#012***** Plugin catchall (1.49 confidence) suggests
**************************#012#012If you believe that httpd should be
allowed name_bind access on the port 85 tcp_socket by default.#012Then you
should report this as a bug.#012You can generate a local policy module to
allow this access.#012Do#012allow this access for now by executing:#012#
ausearch -c 'httpd' --raw | audit2allow -M my-httpd#012# semodule -X 300 -i
[Link]#012
Feb 8 14:03:52 rhcsa9-server1 setroubleshoot[2936]: SELinux is
preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 85.
For complete SELinux messages run: sealert -l d28fbbf2-b7c7-4a6d-a677-
7b498dc14c8c
Feb 8 14:03:52 rhcsa9-server1 setroubleshoot[2936]: SELinux is
preventing /usr/sbin/httpd from name_bind access on the tcp_socket port
85.#012#012***** Plugin bind_ports (99.5 confidence) suggests
************************#012#012If you want to allow /usr/sbin/httpd to
bind to network port 85#012Then you need to modify the port
type.#012Do#012# semanage port -a -t PORT_TYPE -p tcp 85#012 where
PORT_TYPE is one of the following: http_cache_port_t, http_port_t,
jboss_management_port_t, jboss_messaging_port_t, ntop_port_t,
puppet_port_t.#012#012***** Plugin catchall (1.49 confidence) suggests
**************************#012#012If you believe that httpd should be
allowed name_bind access on the port 85 tcp_socket by default.#012Then you
should report this as a bug.#012You can generate a local policy module to
allow this access.#012Do#012allow this access for now by executing:#012#
ausearch -c 'httpd' --raw | audit2allow -M my-httpd#012# semodule -X 300 -i
[Link]#012
If we read through all of that, we can see a couple of things going on
there. First, it tells us that SELinux is preventing httpd from binding to the
port, and then tells us if we want even more detail, we can run sealert -l
d28fbbf2-b7c7-4a6d-a677-7b498dc14c8c. We don't need to do that, since
there's enough info to get going with. Looking further down, it gives us a
couple of suggestions on how to fix it. First, we can change the port type
by running semanage port -a -t PORT_TYPE -p tcp 85 and specifying the port
type, OR... we can create a custom policy by running ausearch -c 'httpd'
--raw | audit2allow -M my-httpd and then follow it with semodule -X 300 -i
[Link]. We're going to choose the latter:
ausearch -c 'httpd' --raw | audit2allow -M my-httpd
semodule -X 300 -i [Link]
Now try starting the service again:

systemctl start httpd


Alright! It works!

Next, we're going to check the files locally:

ls -la /var/www/html

total 12
drwxr-xr-x. 3 root root 57 Feb 7 10:46 .
drwxr-xr-x. 4 root root 33 Feb 1 08:40 ..
-rw-r--r--. 1 root root 18 Feb 1 08:42 file1
-rw-r--r--. 1 root root 168 Feb 1 08:43 file2
-rw-r--r--. 1 root root 32 Feb 1 08:43 file3
Okay, we have three files we need to hit here. Let's give it a shot:

curl [Link]

RHCSA is Awesome!
So far, so good.

curl [Link]

February 2023
Su Mo Tu We Th Fr Sa
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28
Still doing alright... Let's check the last one.

curl [Link]

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">


<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
</body></html>
Damn! We were so close...

Ok, let's see if we can figure out what's going on here. Back to the logs...

grep httpd /var/log/messages


Feb 8 14:26:36 rhcsa9-server1 setroubleshoot[3227]: SELinux is
preventing /usr/sbin/httpd from getattr access on the file
/var/www/html/file3. For complete SELinux messages run: sealert -l
d618c7b8-64e2-42ff-8a6e-03e1cf089356
Feb 8 14:26:36 rhcsa9-server1 setroubleshoot[3227]: SELinux is
preventing /usr/sbin/httpd from getattr access on the file
/var/www/html/file3.#012#012***** Plugin restorecon (94.8 confidence)
suggests ************************#012#012If you want to fix the label.
#012/var/www/html/file3 default label should be
httpd_sys_content_t.#012Then you can run restorecon. The access attempt may
have been stopped due to insufficient permissions to access a parent
directory in which case try to change the following command
accordingly.#012Do#012# /sbin/restorecon -v
/var/www/html/file3#012#012***** Plugin catchall_labels (5.21 confidence)
suggests *******************#012#012If you want to allow httpd to have
getattr access on the file3 file#012Then you need to change the label on
/var/www/html/file3#012Do#012# semanage fcontext -a -t FILE_TYPE
'/var/www/html/file3'#012where FILE_TYPE is one of the following:
NetworkManager_exec_t, NetworkManager_log_t,
NetworkManager_tmp_t, ...OUTPUT_OMITTED... keystone_cgi_content_t,
keystone_cgi_htac
Feb 8 14:26:37 rhcsa9-server1 setroubleshoot[3227]: SELinux is
preventing /usr/sbin/httpd from getattr access on the file
/var/www/html/file3. For complete SELinux messages run: sealert -l
d618c7b8-64e2-42ff-8a6e-03e1cf089356
Feb 8 14:26:37 rhcsa9-server1 setroubleshoot[3227]: SELinux is
preventing /usr/sbin/httpd from getattr access on the file
/var/www/html/file3.#012#012***** Plugin restorecon (94.8 confidence)
suggests ************************#012#012If you want to fix the label.
#012/var/www/html/file3 default label should be
httpd_sys_content_t.#012Then you can run restorecon. The access attempt may
have been stopped due to insufficient permissions to access a parent
directory in which case try to change the following command
accordingly.#012Do#012# /sbin/restorecon -v
/var/www/html/file3#012#012***** Plugin catchall_labels (5.21 confidence)
suggests *******************#012#012If you want to allow httpd to have
getattr access on the file3 file#012Then you need to change the label on
/var/www/html/file3#012Do#012# semanage fcontext -a -t FILE_TYPE
'/var/www/html/file3'#012where FILE_TYPE is one of the following:
NetworkManager_exec_t, NetworkManager_log_t,
NetworkManager_tmp_t, ...OUTPUT_OMITTED... keystone_cgi_content_t,
keystone_cgi_htac
Ok, just like last time, it's showing us what's going on here and giving
suggestions. SELinux is preventing httpd from getattr access to the file. It
suggests we can either restorecon the file, or run semanage fcontext -a -t
FILE_TYPE '/var/www/html/file3' to change the label altogether. Let's take a
look at the directory:
ls -laZ /var/www/html

drwxr-xr-x. 3 root root system_u:object_r:httpd_sys_content_t:s0 57


Feb 7 10:46 .
drwxr-xr-x. 4 root root system_u:object_r:httpd_sys_content_t:s0 33
Feb 1 08:40 ..
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 18
Feb 1 08:42 file1
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 168
Feb 1 08:43 file2
-rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 32
Feb 1 08:43 file3
And we can see that file3 has a different label from the other two. Let's try
the restorecon:
restorecon /var/www/html/file3
And check the directory again:

ls -laZ /var/www/html

drwxr-xr-x. 3 root root system_u:object_r:httpd_sys_content_t:s0 57


Feb 7 10:46 .
drwxr-xr-x. 4 root root system_u:object_r:httpd_sys_content_t:s0 33
Feb 1 08:40 ..
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 18
Feb 1 08:42 file1
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 168
Feb 1 08:43 file2
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 32
Feb 1 08:43 file3
Alright, it's looking better! Now let's try to curl it:

curl [Link]

This file is totally messed up!


Success!!! Alright, last thing is to fix the firewall so external clients can
reach it:

firewall-cmd --add-port=85/tcp --permanent


firewall-cmd --reload
28. Put SELinux on server2 in permissive mode.

Solution to Task 28

vi /etc/selinux/config

### Change the following line:


SELINUX=permissive
29. On server1, modify the bootloader with the following parameters:

Increase the timeout using GRUB_TIMEOUT=10


Add the following line: GRUB_TIMEOUT_STYLE=hidden
Add quiet to the end of the GRUB_CMDLINE_LINUX line

Solution to Task 29

vi /etc/default/grub

### Add or edit the following lines:


GRUB_TIMEOUT=10
GRUB_TIMEOUT_STYLE=hidden
GRUB_CMDLINE_LINUX ### add quiet to the end
### Write and quit the file

grub2-mkconfig -o /boot/grub2/[Link]

### Reboot and watch the boot from the console to verify
systemctl reboot
30. Configure NTP synchronization on both servers. Point them to
[Link].

Solution to Task 30

### On both servers:


vi /etc/[Link]

### Edit the following line (should be line 3):


pool [Link] iburst

### Write and quit, then restart the service:


systemctl restart chronyd

### Check the logs to ensure time is being pulled from the new source:
journalctl -u chronyd

### You should see a line similar to the following at the end:
Feb 14 09:00:48 rhcsa9-server1 chronyd[705]: Selected source [Link]
([Link])
31. Configure persistent journaling on both servers.

Solution to Task 31

### On both servers:


mkdir /var/log/journal
journalctl --flush
ls -la /var/log/journal
32. On server2, create a new 2GiB volume group on /dev/sdb named
"platforms_vg".

Solution to Task 32

First, create an LVM partition in fdisk:

### Enter fdisk


fdisk /dev/sdb

### n for new partition


n

### p for primary


p

### 1 for partition number


1

### Press enter to select the first available sector

### +2G for setting the last sector as 2GiB past the first sector
+2G

### t to change the partition type


t

### l to list all partition types


l

### 8e or lvm to select lvm (lvm is an alias for 8e)


lvm

### w to write and quit


w
Then, create the volume group:

vgcreate platforms_vg /dev/sdb1


33. Under the "platforms_vg" volume group, create a 500MiB logical
volume name "platforms_lv" and format it as ext4.

Solution to Task 33

lvcreate -L 500M -n platforms_lv platforms_vg


mkfs.ext4 /dev/mapper/platforms_vg-platforms_lv

[Link] it persistently under /mnt/platforms_lv.

Solution to Task 34

mkdir /mnt/platforms_lv

### use lsblk -f to get the UUID


lsblk -f

### Add the UUID to /etc/fstab with the mount point


vi /etc/fstab

UUID=<uuid_from_lsblk> /mnt/platforms_lv ext4 defaults 0 0

### Write and quit, then mount all to check that it mounts properly
mount -a
mount
35. Extend the "platforms_lv" volume and partition by 500MiB.

Solution to Task 35

### Run an lvextend including the -r switch to extend both the volume and
filesystem
lvextend -L +500M -r /dev/mapper/platforms_vg-platforms_lv
36. On server2, create a 500MiB swap partition on /dev/sdb and mount it
persistently.

Solution to Task 36

First, create a swap partition in fdisk:


### Enter fdisk
fdisk /dev/sdb

### n for new partition


n

### p for primary


p

### 2 for partition number


2

### Press enter to select the first available sector

### +500M for setting the last sector as 500MiB past the first sector
+500M

### t to change the partition type


t

### l to list all partition types


l

### 82 or swap to select swap (swap is an alias for 82)


swap

### w to write and quit


w
Next, create the swap on the new partition:

mkswap /dev/sdb2
Last, find the UUID and add it to /etc/fstab:

### use lsblk -f to get the UUID


lsblk -f

### Add the UUID to /etc/fstab with the mount point


vi /etc/fstab

UUID=<uuid_from_lsblk> swap swap defaults 0 0

### Write and quit, then activate all swap to check that it mounts properly
swapon -a
swapon
37. On server2, using the remaining space on /dev/sdb, create a volume
group with the name networks_vg.

Solution to Task 37

First, create an LVM partition in fdisk:

### Enter fdisk


fdisk /dev/sdb

### n for new partition


n
### p for primary
p

### 3 for partition number


3

### Press enter to select the first available sector

### Press enter to select the last sector

### t to change the partition type


t

### l to list all partition types


l

### 8e or lvm to select lvm (lvm is an alias for 8e)


lvm

### w to write and quit


w
Now, we need to create the volume group, but looking ahead to task 38, it
says the logical volume needs to be using 8MiB extents, which we need to
configure when we create the volume group:

vgcreate -s 8M networks_vg /dev/sdb3


38. Under the "networks_vg" volume group, create a logical volume with
the name networks_lv. Ensure it uses 8 MiB extents. Configure the volume
to use 75 extents. Format it with the vfat file system and ensure it mounts
persistently on /mnt/networks_lv.

Solution to Task 38

### Create the volume


lvcreate -l 75 -n networks_lv networks_vg

### Install dosfstools and create the file system


dnf install -y dosfstools
[Link] /dev/mapper/networks_vg-networks_lv

### Find the UUID with lsblk


lsblk -f

### Create the directory


mkdir /mnt/networks_lv

### Add the UUID to /etc/fstab


vi /etc/fstab

UUID=<uuid_from_lsblk> /mnt/networks_lv vfat defaults 0 0

### Write and quit, then mount all to check


mount -a
mount
39. On server2, create a 5TB thin-provisioned volume on /dev/sdc called
"thin_vol" backed by a pool called "thin_pool" on a 5GB volume group
called "thin_vg". Format it as xfs and mount it persistently under
/mnt/thin_vol.

Solution to Task 39

For this task, we are using VDO within LVM to create the volume.

First, create the partition for the volume group in fdisk:

### Enter fdisk


fdisk /dev/sdc

### n for new partition


n

### p for primary


p

### 1 for partition number


1

### Press enter to select the first available sector

### +5G for setting the last sector as 5GiB past the first sector
+5G

### t to change the partition type


t

### l to list all partition types


l

### 8e or lvm to select lvm (lvm is an alias for 8e)


lvm

### w to write and quit


w
Then, create the volume group:

vgcreate thin_vg /dev/sdc1


Install VDO, create the volume, and format it as XFS:

dnf install -y vdo


lvcreate --vdo -l 100%FREE -V 5T --name thin_vol thin_vg/thin_pool

### Use the -K flag to prevent the discarding of blocks


[Link] -K /dev/mapper/thin_vg-thin_vol
Last, add the volume to /etc/fstab and mount it

### Find the UUID with lsblk


lsblk -f

### Create the directory


mkdir /mnt/thin_vol

### Add the UUID to /etc/fstab


vi /etc/fstab
UUID=<uuid_from_lsblk> /mnt/thin_vol xfs defaults 0 0

### Write and quit, then mount all to check


mount -a
mount
40. On server1, set a merged tuned profile using the the powersave and
virtual-guest profiles.

Solution to Task 40

dnf install -y tuned


systemctl enable --now tuned
tuned-adm profile powersave virtual-guest
41. On server1, start one stress-ng process with the niceness value of 19.
Adjust the niceness value of the stress process to 10. Kill the stress
process.

Solution to Task 41

dnf install -y stress-ng


nice -n 19 stress-ng -c 1 &

### Enter top and renice the process


top
r
### Select the pid and enter 10
q

pkill stress-ng
42. On server1, as the user cindy, create a container image
from [Link] with the tag web_image.

Solution to Task 42

As root, enable linger for cindy:

loginctl enable-linger cindy


Login separately as cindy. It needs to be a fresh login, do not use su -.
Then build the image:
podman build -t web_image [Link]
If we run a podman images now, we should see the newly created image:
podman images

### Output:
REPOSITORY TAG IMAGE ID CREATED
SIZE
localhost/web_image latest b14526ab4f3a 1 minute ago
243 MB
[Link]/ubi9/ubi latest 10acc174412e 9 days ago
219 MB
43. From the newly created image, deploy a container as a service with
the container name cindy_web. The web config files should map to
~/web_files, and the local port of 8000 should be mapped to the
container's port 80. Create a default page that says "Welcome to Cindy's
Web Server!". The service should be enabled and the website should be
accessible.

Solution to Task 43

First, login separately as cindy. It needs to be a fresh login, do not use su


-.
Now, let's go ahead and create the local directory for the web files and the
default web page for our web server:

mkdir web_files
echo "Welcome to Cindy's Web Server!" > web_files/[Link]
Next, let's fix the general permissions on the directory and file, because
otherwise it will be inaccessible (remember the umask change from task
4):

chmod 755 web_files


chmod 644 web_files/[Link]
Next, we can list the available images by doing podman images:
podman images

### Output:
REPOSITORY TAG IMAGE ID CREATED
SIZE
localhost/web_image latest b14526ab4f3a 1 minutes
ago 243 MB
[Link]/ubi9/ubi latest 10acc174412e 9 days ago
219 MB
Now, let's go ahead and kick off a container that does everything. We're
going to do the podman run command to spin it up, the -d switch to run it in
detached mode, the -p switch to map our local port to our internal
container port, the -v switch to map our local storage to our internal
container storage, the :Z flag to create a custom SELinux label on the
files, the --name switch to name the container, and finally specify the
image we'll be running:
podman run -d -p 8000:80 -v ~/web_files:/var/www/html:Z --name cindy_web
localhost/web_image
We can now see the running container by doing a podman ps:
podman ps

### Output:
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
fb89491cdf08 localhost/web_image:latest /sbin/init 1 minutes ago Up 1
minutes ago [Link]:8000->80/tcp cindy_web
Ok, let's test and make sure we can reach it:

curl [Link]

### Output:
Welcome to Cindy's Web Server!
Now, let's build a service off the container. First we need to create the
directory for the service files, and navigate to it:
mkdir -p .config/systemd/user
cd .config/systemd/user
Next, we need to build the service files of the running container:

podman generate systemd --files --name cindy_web --new

### Check and see the file created:


ls -la

### Output:
drwxrwx---. 3 cindy cindy 69 Feb 15 19:35 .
drwxrwx---. 3 cindy cindy 18 Feb 15 19:34 ..
-rw-r--r--. 1 cindy cindy 792 Feb 15 19:35 container-cindy_web.service
Now, before we enable the service, we have to stop and remove the
running container:

podman stop cindy_web


podman rm cindy_web
Enable and start the service with the --user switch:
systemctl --user enable --now container-cindy_web.service
Now if we check again, we'll see the container running:

podman ps

### Output:
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
5bf2d72dbfa1 localhost/web_image:latest /sbin/init 4 seconds ago Up 5
seconds ago [Link]:8000->80/tcp cindy_web
We can also check the status of the service:

systemctl --user status container-cindy_web

### Output:
● container-cindy_web.service - Podman container-cindy_web.service
Loaded: loaded (/home/cindy/.config/systemd/user/container-
cindy_web.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2023-02-17 11:02:07 CET; 2min 38s
ago
Docs: man:podman-generate-systemd(1)
Process: 1728 ExecStartPre=/bin/rm -f /run/user/1015/container-
cindy_web.[Link]-id (code=exited, status=0/SUCCESS)
Main PID: 1757 (conmon)
Tasks: 15 (limit: 11108)
Memory: 25.5M
CPU: 211ms
CGroup:
/[Link]/[Link]/user@[Link]/[Link]/container-
cindy_web.service
├─1741 /usr/bin/slirp4netns --disable-host-loopback --
mtu=65520 --enable-sandbox --enable-seccomp --enable-ipv6 -c -e 3 >
├─1743 rootlessport
├─1749 rootlessport-child
└─1757 /usr/bin/conmon --api-version 1 -c
5bf2d72dbfa18ef8f250ff36775e2e8c4a6e79dbc418bf007e079fbeab540069 -u
5bf2d72dbf>
Feb 17 11:02:07 rhcsa9-server1 systemd[915]: Starting Podman container-
cindy_web.service...
Feb 17 11:02:07 rhcsa9-server1 podman[1729]:
Feb 17 11:02:07 rhcsa9-server1 podman[1729]: 2023-02-17 11:02:07.632856538
+0100 CET m=+0.112055029 container create 5bf2d72dbfa18ef8>
Feb 17 11:02:07 rhcsa9-server1 podman[1729]: 2023-02-17 11:02:07.684918995
+0100 CET m=+0.164117448 container init 5bf2d72dbfa18ef8f2>
Feb 17 11:02:07 rhcsa9-server1 systemd[915]: Started Podman container-
cindy_web.service.
Feb 17 11:02:07 rhcsa9-server1 podman[1729]: 2023-02-17 11:02:07.690819129
+0100 CET m=+0.170017582 container start 5bf2d72dbfa18ef8f>
Feb 17 11:02:07 rhcsa9-server1 podman[1729]:
5bf2d72dbfa18ef8f250ff36775e2e8c4a6e79dbc418bf007e079fbeab540069
Feb 17 11:02:07 rhcsa9-server1 podman[1729]: 2023-02-17 11:02:07.596761866
+0100 CET m=+0.075960345 image pull localhost/web_image
Alright! Everything looks good!

The last thing we need to do is to update the firewall (as root):

### As root
firewall-cmd --add-port=8000/tcp --permanent
firewall-cmd --reload
Congratulations!!! You're ready for your RHCSA 9 exam!

On Node1

Configure the yum repository for


Node1
QUESTION #2:
Configure Your Node1 VM repository installed the packages distribution is
available via YUM:
- baseos
url=[Link]
- appstream
url=[Link]

ANSWER #2:
[root@node1 ~]# vim /etc/[Link].d/[Link]

[BaseOS]
name=base
baseurl=[Link]
gpgcheck=1
enabled=1

[AppStream]
name=app
baseurl=[Link]
gpgcheck=1
enabled=1

:wq

 To confirm it is configured:

[root@node1 ~]# yum clean all


[root@node1 ~]# yum repolist all

 Both should be enabled


 SUCCESS!!

Fix SELinux Port Issues


QUESTION #3:
FIX SELINUX PORT ISSUES:

 In your system, httpd service has some files in /var/www/html (do


not change or alter files)
 solve the problem, httpd service of your system having some issues,
service is not running on port 82.

ANSWER #3:
 You first try to troubleshoot the issue by restarting httpd:

# THE SETUP:
vim /etc/httpd/conf/[Link]
# change the port number from 80 to 82
:wq

[root@node1 ~]# systemctl restart httpd


Job for [Link] failed because the control process exited with error
code.
See "systemctl status [Link]" and "journalctl -xeu [Link]"
for details.

 But as you can see, the server is failing to launch Apache httpd...

[root@node1 ~]# systemctl status httpd


● [Link] - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/[Link]; enabled; vendor
preset: disabled)
Active: failed (Result: exit-code) since Sun 2023-04-23 08:27:47 IST;
20s ago
Docs: man:[Link](8)
Process: 31826 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
(code=exited, status=1/FAILURE)
Main PID: 31826 (code=exited, status=1/FAILURE)

Apr 23 08:27:47 [Link] systemd[1]: Starting The Apache HTTP


Server...
Apr 23 08:27:47 [Link] httpd[31826]: (13)Permission denied:
AH00072: make_sock: could not bind to address [::]:80
Apr 23 08:27:47 [Link] httpd[31826]: (13)Permission denied:
AH00072: make_sock: could not bind to address [Link]:80
Apr 23 08:27:47 [Link] httpd[31826]: no listening sockets
available, shutting down
Apr 23 08:27:47 [Link] httpd[31826]: AH00015: Unable to open
logs
Apr 23 08:27:47 [Link] systemd[1]: [Link]: Main process
exited, code=exited, status=1/FAILURE
Apr 23 08:27:47 [Link] systemd[1]: [Link]: Failed with
result 'exit-code'.
Apr 23 08:27:47 [Link] systemd[1]: Failed to start The Apache
HTTP Server.

 This is due to SELINUX File Context issues on port 82...


 Let’s run semanage port -l | grep 80 to see what context port 80 is:

[root@node1 ~]# semanage port -l | grep 80


http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443,
9000
jabber_interserver_port_t tcp 5269, 5280

 As you can see the file context is http_port_t so lets add port 82 to
the list.
 If you are unsure or if you forget you can lookup the syntax in
the /etc/ssh/sshd_config file:

[root@node1 ~]# cat /etc/ssh/sshd_config | grep semanage


# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
root@node1:~#

 As you can see they give you the semanage port -a -t http_port_t -p
tcp 82 information in there, so now we'll just have to apply it:

[root@node1 ~]# semanage port -a -t http_port_t -p tcp 82


[root@node1 ~]# semanage port -l | grep 82
amanda_port_t tcp 10080-10082
collected_port_t udp 25826
fac_restore_port_t tcp 55582
fc_port_t tcp 5982
hpip_port_t tcp 2208, 2211, 9220, 9221, 9222
hpss_port_t tcp 6502, 7002
http_port_t tcp 80, 81, 82, 443, 488, 8008, 8009,
8443, 9000
squid_port_t tcp 3128, 3401, 4827
trivnet1_port_t tcp 8200
us_cli_port_t tcp 8082, 8083
varnishd_port_t tcp 6081-6082
 Then, we will start and enable httpd. We can use:

[root@node1 ~]# systemctl enable --now httpd

 Don’t forget to open the port 82 on the firewall:

[root@node1 ~]# firewall-cmd --permanent --add-port=82/tcp


success
[root@node1 ~]# firewall-cmd --reload
success

 Now test httpd out:

[root@node1 ~]# curl [Link]


<H1> Welcome to RHCSA Exam !!!! </H1>

 SUCCESS!!

Additional Comments:
BLUF: There is no need to run restorecon when you invoke semanage port
When you add a port to an SELinux type with semanage port, you're
modifying the policy to allow SELinux to recognize traffic on that port as a
type that has specific rules defined (such as http_port_t for HTTP
services). This adjustment affects how SELinux manages access control
for the port but does not involve file contexts, which are what restorecon
would modify.

Thus, for the action of adding or modifying port contexts, restorecon is not
necessary. The SELinux policy update from semanage is sufficient to apply
the needed changes immediately, without needing to restore file contexts.

Create users and assign them to


secondary groups
QUESTION #4:
Set the default maximum number of days a password may be used to 20
days, then create the following users, groups, and group membership:

 A group named sysadm.


 A user "harry" who belongs to sysadm as a secondary group.
 A user "natasha" who belongs to sysadm as a secondary group.
 A user "sarah" who does not have access to an interactive shell & who is
not a member of sysadm group.
 "harry", "natasha", and "sarah" should all have the password of
"password".
 "sysadm" group has access to add users to the server.
 "harry" user has access to set password for users without asking sudo
password

ANSWER #4:

 The answer is pretty straightforward therefore I will provide just the


commands:

vim /etc/[Link]
.
.
.
# Password aging controls:
#
# PASS_MAX_DAYS Maximum number of days a password may be used.
# PASS_MIN_DAYS Minimum number of days allowed between password
changes.
# PASS_MIN_LEN Minimum acceptable password length.
# PASS_WARN_AGE Number of days warning given before a password
expires.
#
PASS_MAX_DAYS 20
PASS_MIN_DAYS 0
PASS_WARN_AGE 7

:wq
[root@node1 ~]# groupadd sysadm
[root@node1 ~]# useradd -G sysadm harry
[root@node1 ~]# useradd -G sysadm natasha
[root@node1 ~]# useradd sarah -s /sbin/nologin

[root@node1 ~]# passwd harry # provide password for harry


[root@node1 ~]# passwd natasha # provide password for natasha
[root@node1 ~]# passwd sarah # provide password for sarah
 Be sure to run “passwd” for all users to assign passwords. You can
alternatively run these commands in a loop: for i in
{harry,natasha}; do useradd –G sysadm $i; done and the same for the
passwd command.
 To make sure what groups the users belong to here are the
commands:

[root@node1 ~]# id {harry,natasha,sarah}

 You can try to login as sarah but it should not work:

[root@node1 ~]# su - sarah

 Next, we need to search for the binary path of the command useradd so
we can update the sudoers file:
[root@node1 ~]# visudo
ADD THIS LINE BELOW THE %wheel LINE:

%sysadm ALL=(ALL) /usr/sbin/useradd


and

harry ALL=(ALL) NOPASSWD: /usr/bin/passwd

 So Harry can change passwords without sudo privileges (TO BE


USED WITH CAUTION!!)
 SUCCESS!!

Note: You can alternatively:


If you just performed useradd harry and useradd natasha only, you can
modify their memberships:
[root@node1 ~]# usermod -aG sysadm harry
[root@node1 ~]# usermod -aG sysadm natasha

 You can set the primary group by using a little "g" instead.

Create a shared directory by


group
QUESTION #5:
Create a collaborative directory /shared/sysadm with the following
characteristics:
- Group ownership of /shared/sysadm is sysadm.
- The directory should be readable, writable, and accessible to member of
sysadm, but not to any other user.
- (It is understood that root has access to all files and directories on the
system.)
- Files created in /shared/sysadm automatically have group ownership set
to the sysadm group.
- Finally, we will add two users to the group to give them access to the
shared folder.

ANSWER #5:
 As mentioned above - creation of user was covered in
Lab 04_create_users_with_secondary_groups.
 First we create a directory which is pretty straightforward (however
creating user-related folders in root hierarchy is not a good idea)

[root@node1 ~]# mkdir -p /shared/sysadm

 Then we create the group and assign it as group owner of the created
folder:

[root@node1 ~]# groupadd sysadm


[root@node1 ~]# chgrp sysadm /shared/sysadm

 Here is the most tricky part. To achieve our goal we will be using SETGUID
or SGID, which is a concept that users operating on the files are given the
same permissions like to group owner of the folder/file. We've already set
group owner for the folder so now we assign permissions to it.

[root@node1 ~]# chmod 2770 /shared/sysadm

 Notice the 2 prefix in the access rights. This is a Special Permission


Bit that sets up SGID.
 That means that any user from the group that owns the file/folder will be
given group permissions when operating on it.
 It simplifies administration as You do not have to give users access
via ACLs to the folder, rather than just assign them to the group and
that's it.

 Finally we need to remember to actually add our users to the mentioned


group sysadm.

[root@node1 ~]# usermod -aG sysadm harry


[root@node1 ~]# usermod -aG sysadm natasha

 SUCCESS!!

Additional comment:

 It is possible to change user's primary group for the current session


using newgrp command.

Add entry to cron


Question #6 Part 1:
Use Cron to setup two scheduled tasks:

 Set a Cron Job for the user "Natasha" which runs daily every minute local
time, and executes "Ex200 Testing" with logger.
 Set another Cron Job for the user "Nastasha" which runs daily at 2:30pm
local time, and executes "Hello World".
Answer #6:

 You may reference the syntax setting up cron tasks by running:

[root@node1 ~]# cat /etc/crontab


SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:


# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR
sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed

 Run the crontab command for user natasha:

[root@node1 ~]# which logger


/bin/logger
[root@node1 ~]# crontab -eu natasha

* * * * * /usr/bin/logger "Ex200 Testing"

:wq

 Let's set another cron job an echo "Hello World" message which will go off
at 2:30pm every day:

[root@node1 ~]# crontab -eu natasha

* * * * * /bin/logger "Ex200 Testing"


30 14 * * * /bin/echo "Hello World"

:wq

 Now let's see what cron jobs are setup under user natasha:

[root@node1 ~]# crontab -lu natasha


* * * * * /usr/bin/logger "Ex200 Testing"
30 14 * * * /bin/echo "Hello World"

 SUCCESS!!
Setting Up the at Command
The at command is used to schedule commands to be executed at a
particular time in the future. Here’s how to install and enable it:

 Install the at package:

[root@node1 ~]# install at


[root@node1 ~]# systemctl enable --now atd

 Schedule a task to run five minutes from the current time. It will create a
text file in /tmp with the content "Hello, world!":

[root@node1 ~]# echo "echo 'Hello, world!' > /tmp/[Link]" | at now + 5


minutes

 To list scheduled jobs:

[root@node1 ~]# atq

 View a specific job:

[root@node1 ~]# at -c <job number>

 Remove a scheduled job:

[root@node1 ~]# atrm <job number>

 For more information:

man at

 SUCCESS!!

Additional comments:

 The log file does not need to exist - it will be created automatically. \
 Of course root user can edit crontab of every user with flag -u specifying
user name. \
 It is worth remembering that there
are /etc/[Link] and /etc/[Link].

Configure autofs on Node1


(Updated on 7/8/2025)
QUESTION #7 See Lab #00 YOU MUST SET THIS UP
PRIOR TO STARTING THIS ONE!
Configure autofs to automount the home directories of remoteuserx user.
Note the following:

 remoteuserx's directory is exported via NFS, which is available on


[Link] ([Link]) and your NFS-exports directory
is /ourhome/remoteuserx for remoteuserx,
 remoteuserx's home directory should be automounted using autofs
service.
 home directories must be writable by their users.

DexTutor Tutorial can be found here

ANSWER #7:

* BEFORE YOU BEGIN THIS LAB, PLEASE START


WITH LAB 00_ansible-nfs_server_configuration AND SETUP NFS
ON THAT MACHINE. THEN YOU MAY PROCEED:

 You will need to create an NFS test user (On the exam it may already be
created). This part is done on the NFS Server ([Link] or
[Link]):

[root@ansible ~]# groupadd -g 1234 autofsusers


[root@ansible ~]# useradd -d /ourhome/remoteuserx -u 1234 -g autofsusers
remoteuserx
[root@ansible ~]# passwd remoteuserx
# Make sure to set a password for remoteuserx

 Then, you need to install autofs and nfs-utils:

[root@node1 ~]# yum install -y autofs nfs-utils


[root@node1 ~]# systemctl enable --now autofs

 Create a new autofs master map file for /ourhome:

[root@node1 ~]# vim /etc/[Link].d/[Link]

/ourhome /etc/[Link]

:wq
 Create and Edit the Indirect Map File: Create and edit
the /etc/[Link] file. This file will define the specific automount
for remoteuserx within the /ourhome base path.

[root@node1 ~]# vim /etc/[Link]

#
# This is an automounter map and it has the following format
# key [ -mount-options-separated-by-comma ] location
# Details may be found in the autofs(5) manpage

cd -fstype=iso9660,ro,nosuid,nodev
:/dev/cdrom

# the following entries are samples to pique your imagination


#linux -ro,soft
[Link]:/pub/linux
#boot -fstype=ext2
:/dev/hda1
#floppy -fstype=auto
:/dev/fd0
#1floppy -fstype=ext2
:/dev/fd0
#e2floppy -fstype=ext2
:/dev/fd0
#jaz -fstype=ext2
:/dev/sdc1
#removable -fstype=ext2
:/dev/hdd
remoteuserx -rw,soft,intr
[Link]:/ourhome/remotueserx

:wq

 Restart the autofs service. The mount -a command is not necessary for
autofs as it's triggered on access.

[root@node1 ~]# systemctl restart autofs


[root@node1 ~]# mount -a

 Let's test it out, but before we do, notice that the partition is NOT YET
MOUNTED:

[root@node1 ~]# cd /ourhome


[root@node1 ourhome]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 846M 0 846M 0% /dev
tmpfs 875M 0 875M 0% /dev/shm
tmpfs 350M 9.6M 341M 3% /run
/dev/sda2 5.6G 3.7G 2.0G 66% /usr
/dev/mapper/myvg-home 9.5G 6.0M 8.9G 7% /lvm1
/dev/sr0 8.0G 8.0G 0 100% /dvd
/dev/sda7 947M 39M 908M 5% /tmp
/dev/sda6 947M 44M 904M 5% /home
/dev/sda1 947M 256M 692M 27% /boot
/dev/sda5 1.9G 202M 1.7G 11% /var
tmpfs 175M 92K 175M 1% /run/user/0
 Next, let's run ls and df -h within the /ourhome directory:

[root@node1 ourhome]# ls
remotueserx

[root@192 ourhome]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 846M 0 846M 0% /dev
tmpfs 875M 0 875M 0% /dev/shm
tmpfs 350M 9.6M 341M 3% /run
/dev/sda3 1.9G 78M 1.8G 5% /
/dev/sda2 5.6G 3.7G 2.0G 66% /usr
/dev/mapper/myvg-home 9.5G 6.0M 8.9G 7% /lvm1
/dev/sr0 8.0G 8.0G 0 100% /dvd
/dev/sda7 947M 39M 908M 5% /tmp
/dev/sda6 947M 44M 904M 5% /home
/dev/sda1 947M 256M 692M 27% /boot
/dev/sda5 1.9G 202M 1.7G 11% /var
tmpfs 175M 92K 175M 1% /run/user/0
[Link]:/ourhome/remoteuserx 1.9G 179M 1.7G 10%
/ourhome/remoteuserx

 SUCCESS!!

Create a tar archive of a file


QUESTION #8
Create a tar archive of "/etc/" Directory with .bz2 extension:

 Tar archive named "[Link].bz2" should be placed in "/root/"


Directory.

ANSWER #8:

 Use the -j to handle .bz2 compression:

[root@node1 ~]# tar -cvjf /root/[Link].bz2 /etc/


tar: Removing leading '/' from member names
/etc/
/etc/mtab
/etc/fstab
/etc/crypttab
/etc/lvm/
/etc/lvm/devices/
/etc/lvm/devices/[Link]
/etc/lvm/archive/
/etc/lvm/archive/rhel_192_00000-[Link]
 OR if the question asks you to use .gz for compression, use -z instead:

[root@node1 ~]# tar -cvzf /root/[Link] /etc/


tar: Removing leading '/' from member names
/etc/
/etc/mtab
/etc/fstab
/etc/crypttab
/etc/lvm/
/etc/lvm/devices/
/etc/lvm/devices/[Link]
/etc/lvm/archive/
/etc/lvm/archive/rhel_192_00000-[Link]

 OR if the question asks you to use .xz, use -J instead for compression:

[root@node1 ~]# tar -cvJf /root/[Link] /etc/


tar: Removing leading `/' from member names
/etc/
/etc/mtab
/etc/fstab
/etc/crypttab
/etc/[Link]
/etc/dnf/
/etc/dnf/modules.d/
/etc/dnf/aliases.d/
/etc/dnf/[Link]
/etc/dnf/[Link].d/
/etc/dnf/plugins/

 SUCCESS!!

Configure file access control list


(ACL) rights to a file
QUESTION #9:
Copy the file /etc/fstab to /var/tmp. Configure the permissions of
/var/tmp/fstab so that:
- the file /var/tmp/fstab is owned by the root user
- the file /var/tmp/fstab belong to the group root
- the file /var/tmp/fstab should not be execubable by anyone
- the user "natasha" is able to read and write /var/tmp/fstab
- the user "harry" can neither write nor read /var/tmp/fstab
- all other users (current or future) have the ability to read /var/tmp/fstab
ANSWER #9:

 We start with copying the file with permissions it already has:

[root@node1 ~]# cp /etc/fstab /var/tmp


[root@node1 ~]# ls -l /var/tmp/fstab
-rw-r--r--. 1 root root 583 Apr 23 08:52 /var/tmp/fstab

 We have to create users mentioned in question (if we do not have them


already):

useradd natasha
useradd harry

 Setting special access rights to files/directories is achieved via FACL. The


commands are:

[root@node1 ~]# setfacl -m u:natasha:rw- /var/tmp/fstab


[root@node1 ~]# setfacl -m u:harry:--- /var/tmp/fstab
[root@node1 ~]# getfacl /var/tmp/fstab
getfacl: Removing leading '/' from absolute path names
# file: var/tmp/fstab
# owner: root
# group: root
user::rw-
user:harry:---
user:natasha:rw-
group::r--
mask::rw-
other::r--

 SUCCESS!!

 Additional Comments:
o By default all other users can read this file so this requirement is
already met.

Configure Chrony for Time


Synchronization
QUESTION #10:
Configure your system to synchronize the time to the Ansible
Workstation, [Link].
ANSWER #10:

 Install and configure chronyd on Node1:

[root@node1 ~]# yum install chrony


[root@node1 ~]# vim /etc/[Link]

 Comment out the 'pool' line and add this 'server' line below it:

#pool [Link] iburst


server [Link] iburst maxpoll 16

 Now SSH to Ansible or open it up in another tab to open the firewall:

[root@ansible ~]# firewall-cmd --permanent --add-service=ntp


success
[root@ansible ~]# firewall-cmd --reload
success

 Now, go back to Node1, and restart the Chronyd service and enable it so it
starts at boot-time:

[root@node1 ~]# systemctl restart chronyd


[root@node1 ~]# systemctl enable chronyd

 Finally, to get time synchronization working:

[root@node1 ~]# timedatectl set-ntp true

 You may check your work by running:

[root@node1 ~]# chronyc sources -v

.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = current best, '+' = combined, '-' = not combined,
| / 'x' = may be in error, '~' = too variable, '?' = unusable.
|| .- xxxx [ yyyy ] +/-
zzzz
|| Reachability register (octal) -. | xxxx = adjusted
offset,
|| Log2(Polling interval) --. | | yyyy = measured
offset,
|| \ | | zzzz = estimated
error.
|| | | \
MS Name/IP address Stratum Poll Reach LastRx Last sample
===========================================================================
====
^* [Link] 2 6 377 27 -15us[ -20us] +/- 205us

 SUCCESS!!
Additional comment:
The old method of time synchronization in RHEL 6 was Ntpd. This has
been completely sunset by Chronyd since RHEL 7.

Find Files Using Specific


Parameters (Updated on
7/8/2025)
On Node1

QUESTION #11 (Part 1):


Find all the files in the /etc directory (not subdirectories) where the files
were modified more than 180 days ago, then copy all of them to
the /var/tmp/pvt directory.

ANSWER #11 (Part 1):

 The find command provides what is needed:

find /etc -type f -maxdepth 1 -mtime +180 -exec cp {} /var/tmp/pvt \;

QUESTION #11 (Part 2):


Find all files and directories which are owned by the user natasha in this
system, then copy them into the /root/natashafiles directory.

ANSWER #11 (Part 2):


 Run the find command with the -user option and use -exec to copy
to the directory:
 You can alternatively divert the errors in the output using /dev/null:
find / -user natasha -exec cp -rf {} /root/natashafiles/ \; 2>/dev/null
 Alternatively, the test may ask you to put this into a script:

vim /opt/[Link]

 Don’t forget to give the .sh file execute permissions:

chmod 755 /opt/[Link]

 NOTE: If you want to be able to run the script from any terminal:

cp /opt/[Link] /usr/local/bin/

QUESTION #11 (Part 3):


On Node1, find all files in the system that have the setuid bit set and save
their paths to /root/setuid_files.txt.

ANSWER #11 (Part 3):

 Use the find command with -perm -4000 to find files with the setuid bit set
across the entire system:

find / -type f -perm -4000 -print > /root/setuid_files.txt 2>/dev/null

 Note: The 2>/dev/null redirects permission-denied errors to avoid


cluttering the output.

QUESTION #11 (Part 4):


On Node1, find all files in the system that have the setgid bit set and save
their paths to /root/setgid_files.txt.

ANSWER #11 (Part 4):

 Use the find command with -perm -2000 to find files with the setgid bit set
across the entire system:

find / -type f -perm -2000 -print > /root/setgid_files.txt 2>/dev/null

 SUCCESS!!
Explanation of Parts 3 and 4:

Part 3: Finding SUID Files

 Purpose: Identifies files with the setuid bit set (e.g., permissions like -
rwsr-xr-x or 4755), allowing them to execute with the privileges of their
owner, often root. Examples include /usr/bin/passwd and /usr/bin/su.
 Command Breakdown:
o find /: Searches the entire filesystem.
o -type f: Limits the search to files only.
o -perm -4000: Matches files with the setuid bit set.
o -print: Prints the full path of matching files (default behavior,
included for clarity).
o > /root/setuid_files.txt: Saves the results to a file.
o 2>/dev/null: Suppresses permission-denied errors.

Part 4: Finding SGID Files

 Purpose: Identifies files with the setgid bit set (e.g., permissions like -
rwxr-sr-x or 2755), allowing them to run with the privileges of the group
owner. It’s also used on directories to enforce group ownership
inheritance.
 Command Breakdown:
o find /: Searches the entire filesystem.
o -type f: Limits the search to files only.
o -perm -2000: Matches files with the setgid bit set.
o -print: Prints the full path of matching files (default behavior,
included for clarity).
o > /root/setgid_files.txt: Saves the results to a file.
o 2>/dev/null: Suppresses permission-denied errors.

Search for string using grep and


redirect the output
QUESTION #12:
Find all strings "ich" from "/usr/share/dict/words" file and copy those
strings in a /root/lines file.
ANSWER #12:

 The grep command provides what is needed:

[root@node1 ~]# grep ich /usr/share/dict/words > /root/lines


SUCCESS!!

UPDATED ON 2025-03-13:
Tutorial Video Link Here

On Node2

Reset the root password on


Node2 / "Breaking into the
System"
QUESTION #13:
You do not know the root password on Node2, but You have physical access
to the machine. Create a new root password and log into the system. (It
can be preliminary task for starting Your exam. It is crucial to know this
procedure by heart.)

ANSWER #13:

Resetting the Root Password


(RHEL 9)
Objectives
 Reset the root password using this technique:
Instructions:

1. Reboot the System

2. Edit the GRUB Boot Parameters

 Use the cursor keys to highlight the first option, then press e to edit
the boot parameters.

 Now, move the cursor to the 3rd line that starts with linux.
 At the end of this line, add the following parameters:
 init=/bin/bash

 # Also don't forget to change the 'ro' to 'rw' in the middle of that
line. See example screen below

 Press Ctrl+x to boot with the modified parameters.

3. Access the Root Shell


 The system will boot into a single-user mode with a root shell prompt.

4. Reset the Root Password

 Set a new root password by executing:

passwd

 Follow the prompts to enter and confirm the new password.

5. Force SELinux to Relabel

 Force SELinux to relabel during the next boot.

touch /.autorelabel

Important: The SELinux relabel in this method is required. SELinux


detects whether an alternative access sequence occurred because the
SELinux contexts are no longer present on the modified files. To trust the
system again, SELinux will not boot until all files are properly relabeled.

6. Reboot the System

exec /sbin/init

7. Verify the Root Password

 Verify that the root password access is reset by either logging in


as root or by logging in as a non-privileged user and switching to
root with any method that requires entering the root password.

SUCCESS!!

UPDATED ON 2025-03-10:

On Node2

Configure Yum Repository


QUESTION #14:
Configure Your Node2 VM repository installed the packages distribution is
available via YUM:
- baseos
url=[Link]
- appstream
url=[Link]

ANSWER #14:

 First, let's create the repository. You can copy the text from Node1's
/etc/[Link].d/[Link]:

[root@node2 ~]# vim /etc/[Link].d/[Link]

[BaseOS]
name=BaseOS
baseurl=[Link]
gpgcheck=0
enabled=1

[AppStream]
name=AppStream
baseurl=[Link]
gpgcheck=0
enabled=1

:wq
[root@node2 ~]# yum repolist

UPDATED 2025-03-13:

On Node2

Lab #15: Logical Volume


Management (LVM)
Objective:
Create and manage Logical Volumes using parted
QUESTION #15.1:
Create a Logical Volume named LV1 of size 8GB using the extra storage
provided. Here is what you will learn:

DexTutor's tutorial can be found here

ANSWER #15.1:

 First, if you are running virtual machines, you will need to add an
additional storage device here...6GB,5GB, and 4GB "Hard Disks"
 You can shut down the virtual machine and then add the additional
storage as needed.

Step 1: Verify Attached Storage


[root@node2 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sro 11:0 1 1024M 0 rom
vda 252:0 0 10G 0 disk
├─vda1 252:1 0 1G 0 part /boot
├─vda2 252:2 0 9G 0 part
│ ├─_rhe1_192-root 253:0 0 8G 0 lvm /
│ └─_rhe1_192-swap 253:1 0 1G 0 lvm [SWAP]
vdb 252:16 0 6G 0 disk
vdc 252:17 0 5G 0 disk
vdd 252:18 0 4G 0 disk

Step 2: Prepare Disks with parted


Execute these commands for each new disk (/dev/vdb, /dev/vdc, /dev/vdd):
[root@node2 ~]# parted /dev/vdb mklabel gpt
[root@node2 ~]# parted -s /dev/vdb mkpart primary xfs 0% 100%
[root@node2 ~]# parted /dev/vdb set 1 lvm on
Repeat similarly for /dev/vdc and /dev/vdd.

Step 3: Verify Partitioning


lsblk

Step 4: Create Physical Volumes


[root@node2 ~]# pvcreate /dev/vdb /dev/vdc /dev/vdd

# We can verify that they are available:


[root@node2 ~]# pvs
PU VG Fmt Attr PSize PFree
/dev/sdb 1um2 --- 6.00g 6.00g
/dev/sdc 1vm2 --- 5.00g 5.00g
/dev/sdd 1um2 --- 4.00g 4.00g

Step 5: Create Volume Group


[root@node2 ~]# vgcreate VG1 /dev/sdb /dev/sdc
Volume group "VG1" successfully created

# Verify the new VG1 has been created:


[root@node2 ~]# vgs
VG #PU #LV #SN Attr VSize VFree
VG1 2 0 0 wz--n- 10.99g 10.99g

Step 6: Create Logical Volume (LV1) using 8GB


[root@node2 ~]# lvcreate -L 8Gb -n LV1 VG1
Logical volume "LV1" created.

# Verify:
[root@node2 ~]# lvs
LV VG Attr LSize Pool Origin Data Metax Move Log Cy Sync
Convert
LV1 VG1 wi-a-- 8.00g

Step 7: Format and Mount Logical Volume


[root@node2 ~]# [Link] /dev/VG1/LV1
[root@node2 ~]# mkdir /lv
Step 8: Automate Mounting with /etc/fstab
[root@node2 ~]# echo "/dev/VG1/LV1 /lv xfs defaults,nodev 0 0" >>
/etc/fstab

Step 9: Instantly mount the LVM without a reboot


[root@node2 ~]# mount -a

 SUCCESS!!

QUESTION #15.2:
Extend the Logical Volume you created, LV1 by 2GB.

Again, DexTutor's tutorial can be found here

ANSWER #15.2:

Step 1: Extend Logical Volume by 2GB


Check available space first:

[root@node2 ~]# vgs


VG #PV #LV #SN Attr VSize VFree
VG1 2 1 0 wz--n- 10.99g 2.99g
If space permits on VG1 with the 2 physical disks:
[root@node2 ~]# lvextend -r -L +2G /dev/VG1/LV1

# Verify:
[root@node2 ~]# lvs

Step 2: Extend Volume Group VG1 to /dev/sdd


If you need more space:

[root@node2 ~]# vgextend VG1 /dev/vdd


[root@node2 ~]# lvextend -r -L +2G /dev/VG1/LV1

Step 3: Verify New Size


[root@node2 ~]# df -h

 SUCCESS!!
QUESTION #15.3:
Create a Logical Volume named LV2 with 10 extent where the size of each
extent is 8MB.

DexTutor's tutorial can be found here

ANSWER #15.3:
Step 1: Check Current Volume Group Configuration

[root@node2 ~]# vgdisplay


Step 2: If current PE size isn't 8MB, recreate the volume group:

[root@node2 ~]# umount -l /lv


[root@node2 ~]# lvchange -an /dev/VG1/LV1
[root@node2 ~]# lvremove /dev/VG1/LV1
[root@node2 ~]# vgremove VG1
Step 3: Create a new Volume Group with 8MB extents:

[root@node2 ~]# vgcreate -s 8MB VG1 /dev/vdb


[root@node2 ~]# vgdisplay VG1
Step 4: Create Logical Volume LV2 with 10 extents:
[root@node2 ~]# lvcreate -l 10 -n LV2 VG1
[root@node2 ~]# lvs
Your Logical Volume LV2 is now set up successfully with custom extent
size.

 SUCCESS!!

Troubleshooting:
Remove existing configuration if required and recreate:

[root@node2 ~]# umount -l /lv


[root@node2 ~]# lvchange -an /dev/VG1/LV1
[root@node2 ~]# lvremove /dev/VG1/LV1
[root@node2 ~]# vgremove VG1
[root@node2 ~]# vgcreate -s 8MB VG1 /dev/vdb
[root@node2 ~]# vgdisplay VG1

Conclusion
You've successfully configured Logical Volume Management using parted,
managing and adjusting logical volumes as required.

On Node2

Create a Soft Link


QUESTION #16:
Create a soft link for /var/log/messages in the /root directory.

ANSWER #16:

 This is pretty straight forward, but you need to know that the source file
you are referencing comes first, then the location you want to put it.
 THE SYNTAX IS ln -s <src> <dst>

[root@node2 ~]# ln -s /var/log/messages /root


[root@node2 ~]# ls -l /root
-rw-r--r--. 1 root root 591 Nov 2 2022 [Link]
lrwxrwxrwx. 1 root root 17 May 2 19:06 messages -> /var/log/messages
-rw-r--r--. 1 root root 54 May 2 19:04 [Link]
-rw-r--r--. 1 root root 5121 Jun 3 2022 [Link]
-rw-r--r--. 1 root root 43 May 2 19:03 [Link]

[root@node2 ~]# tail -n 5 /root/messages


May 2 19:05:54 rhel-9-1-6-20-2023 systemd[1]: cockpit-wsinstance-
[Link]: Deactivated successfully.
May 2 19:05:54 rhel-9-1-6-20-2023 systemd[1]: Closed Socket for Cockpit
Web Service http instance.
May 2 19:05:54 rhel-9-1-6-20-2023 systemd[1]: cockpit-wsinstance-https-
[Link]: Deactivated successfully.
May 2 19:05:54 rhel-9-1-6-20-2023 systemd[1]: Closed Socket for Cockpit
Web Service https instance factory.
May 2 19:06:10 rhel-9-1-6-20-2023 systemd[1]: [Link]:
Deactivated successfully.
total 20

 Now, let's check the inode number on the far left of the output. They
should be different:

[root@node2 ~]# ls -li /var/log/messages


5850 -rw-------. 1 root root 130632 May 2 19:13 /var/log/messages
root@node2:~# ls -li /root/messages
295363 lrwxrwxrwx. 1 root root 17 May 2 19:06 /root/messages ->
/var/log/messages

 SUCCESS!!
On Node2

Create swap partition


QUESTION #16:
Create a swap partition of 400MB and make it available permanent.

ANSWER #16:
 Before any kind of operations on LVM it is good to know what we
actually have in the system. The proper command to list all devices
we can use is in order pvs, vgs and lvs. It shows all physical
storages and devices, volume groups and logical volumes.
 First we create a logical volume that is mentioned in the question
and we create swap on it:

[root@node2 ~]# fdisk /dev/vdb

Welcome to fdisk (util-linux 2.37.4).


Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
This disk is currently in use - repartitioning is probably a bad idea.
It's recommended to unmount all file systems, and swapoff all swap
partitions on this disk.

Command (m for help):

 Type “n”, “p”, and then “+400M”:

Command (m for help): n


Partition type
p primary (0 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (1-4, default 2): 2
First sector (2048-10485759, default 1026048): 1026048
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1026048-10485759, default
10485759): +400M
Created a new partition 2 of type 'Linux' and of size 400 MiB.

 Change the partition: Hit "t" for type, "2" for partition 2, "82" for swap,
then “w” to write it:

Command (m for help): t


Partition number (1,2, default 2): 2
Hex code or alias (type L to list all): 82
Changed type of partition 'Linux' to 'Linux swap / Solaris'.
 Don’t forget to run partprobe:

[root@node2 ~]# partprobe /dev/vdb


Format the new swap partition on vdb2, then add it to the main swap:
[root@node2 ~]# mkswap /dev/vdb2 Setting up swapspace version 1, size
= 400 MiB (419426304 bytes) no label, UUID=9abc60cf-9d66-4d3a-8ffe-
218770ee99ad

[root@node2 ~]# swapon /dev/vdb2

 Type “blkid” to find the UUID #:

[root@node2 ~]# blkid | grep vdb2


/dev/vdb2: UUID="9abc60cf-9d66-4d3a-8ffe-218770ee99ad" TYPE="swap"
PARTUUID="d0ae2e9f-02"

 To make swap changes permanent as usual /etc/fstab must be changed:

# /etc/fstab
# Created by anaconda on Fri Dec 30 16:18:12 2022
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more
info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
/dev/mapper/rhel_192-root / xfs defaults 0
0
UUID=0efecb9e-7ecd-47e0-ad64-507f7c994e18 /boot xfs defaults 0
0
/dev/mapper/rhel_192-swap none swap defaults 0
0
/dev/mapper/wgroup-wshare /mnt/wshare ext4 defaults 0
0
UUID=9abc60cf-9d66-4d3a-8ffe-218770ee99ad swap swap defaults 0
0
[root@node2 ~]# systemctl daemon-reload

 Run “mount -a” to mount the swap partition:

[root@node2 ~]# mount -a

 Run the swapon -s command to add the swap volume to the main swap
volume:

[root@node2 ~]# swapon -s


Filename Type Size Used
Priority
/dev/dm-1 partition 1048572 0 -1
/dev/vdb2 partition 409596 0 -2

 To check swap/memory statistics:

free -k
 SUCCESS!!

Additional comment:
Both commands mkswap and swapon have parameters like -L and -U so
it is possible to give these commands not only the path (to the file or
partition) but label or UUID.

On Node2

Configure Tuned
QUESTION #18:
Configure the recommended tuned profile.

ANSWER #18:

 Install the "tuned" package:

[root@node2 ~]# yum install tuned


Installed:
hdparm-9.62-2.el9.x86_64 python3-linux-procfs-0.7.0-
[Link]
python3-perf-5.14.0-72.20.1.el9_0.x86_64 python3-pyudev-0.22.0-
[Link]
[Link]
Complete!

 Start and enable the tuned service:

[root@node2 ~]# systemctl enable --now tuned

 Run tuned-adm list:

[root@node2 ~]# tuned-adm list


Available profiles:
- accelerator-performance - Throughput performance based tuning
with disabled high latency operations
- balanced - General non-specialized tuned profile
- desktop - Optimize for the desktop use-case
- hpc-compute - Optimize for HPC compute workloads
- intel-sst - Optimize for Intel Speed Select Base
Frequency
- latency-performance - Optimize for deterministic performance
at the cost of increased power consumption
- network-latency - Optimize for deterministic performance
at the cost of increased power consumption, focused on low latency network
performance
- network-throughput - Optimize for streaming network
throughput, generally decreases power consumption
- optimize-serial-console - Optimize for serial console use.
- powersave - Optimize for low power consumption
- throughput-performance - Broadly applicable tuning that provides
excellent performance across a variety of common server workloads
- virtual-guest - Optimize for running inside a virtual
guest
- virtual-host - Optimize for running KVM guests
Current active profile: virtual-guest

 Run tuned-adm recommend:

[root@node2 ~]# tuned-adm recommend


virtual-guest

 Set the profile to the one recommended:

[root@node2 ~]# tuned-adm profile virtual-host

 To check which profile is active:

[root@node2 ~]# tuned-adm active


Current active profile: virtual-host

 SUCCESS!!

Additional Comments:
This lab is setup in such a way that the tuned-adm profile is already on
the recommended, which is fine. You can alter it and then change it back
for the sake of this lab.

On Node2

Create a Very Basic Application


QUESTION #19:
Build an application rhcsa that print the message when logged in as
ablerate user: "Welcome to user ablerate."
ANSWER #19:

 Create the user if it doesn’t exist:

[root@node2 ~]# useradd ablerate


[root@node2 ~]# passwd ablerate
Changing password for user ablerate.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
[root@node2 ~]#

 Here we make a script-style application in /usr/local/bin called "rhcsa":

[root@node2 ~]# vim /usr/local/bin/rhcsa

#! /bin/bash
echo "Welcome to user ablerate"

:wq

 Next, we give executable permissions on that file:

[root@node2 ~]# chmod +x /usr/local/bin/rhcsa

 Edit the user's /home/abelrate/.bashrc:

[root@node2 ~]# vim /home/ablerate/.bashrc

# User specific aliases and functions


if [ -d ~/.bashrc.d ]; then
for rc in ~/.bashrc.d/*; do
if [ -f "$rc" ]; then
. "$rc"
fi
done
fi

/usr/local/bin/rhcsa

:wq

 Double-check the permissions:

[root@node2 ~]# ls -l /usr/local/bin/rhcsa


-rwxr-xr-x. 1 root root 44 Apr 23 09:48 /usr/local/bin/rhcsa

 To check your work for the user’s welcome message:

[root@node2 ~]# su - ablerate


Welcome to user ablerate.

 SUCCESS!!
On Node2

Container Build
QUESTION #20:
Download containerfile from [Link]
PDF/archive/refs/heads/[Link]

 Do not make any modification.


 Build image with this container file.

ANSWER #20:

 First, you will need to install the Container Management Group packages:

[root@node2 ~]# yum install @”Container Management"

 Then, switch to the account of user that will be running the container (It is
assumed that user named andrew exists on the system):

[root@node2 ~]# ssh andrew@localhost


[andrew@localhost ~]$ wget
[Link]
[Link]
[andrew@localhost ~]$ unzip [Link]
[andrew@localhost ~]$ rm -rf [Link]
[andrew@localhost ~]$ cd Text-To-PDF-master
[andrew@localhost ~]$ podman build -t myapp .

 To check: Type podman image ls or podman images:

[andrew@localhost ~]$ Text-To-PDF-master]$ podman image ls


REPOSITORY TAG IMAGE ID CREATED
SIZE
localhost/myapp Latest 9ba525b6e56a 17 seconds
ago 479 MB
[Link]/fedora Latest 0e79e93fc530 2 days ago
196 MB

 SUCCESS!!

Alternatively you may try this Containerfile:


git clone [Link]
Containers101
Rootless Containers with
Podman: The Basics
As a developer, you have probably heard a lot about containers. A
container is a unit of software that provides a packaging mechanism that
abstracts the code and all of its dependencies to make application builds
fast and reliable. An easy way to experiment with containers is with the
Pod Manager tool (Podman), which is a daemonless, open source, Linux-
native tool that provides a command-line interface (CLI) similar to the
Docker container engine.

In this document, we will:

 Explain the benefits of using containers and Podman


 Introduce rootless containers and their importance
 Show how to use rootless containers with Podman through a practical
example

1. Why Containers?
Containers isolate your applications from the underlying computing
environment. They bind application logic and dependencies into a single
unit, enabling developers to focus on code rather than environment
discrepancies. Operations teams benefit by managing application
deployment without worrying about software versions or configuration.

Containers virtualize at the operating system (OS) level, making them


lightweight compared to virtual machines (VMs), which virtualize at the
hardware level. Key advantages:

 Low hardware footprint


 Environment isolation
 Quick deployment
 Multiple environment deployments
 Reusability

2. Why Podman?
Podman simplifies finding, running, building, sharing, and deploying
OCI-compatible containers and images. Its main advantages include:

 Daemonless: No central service is required, unlike Docker.


 Layer control: Fine-grained management of image layers.
 Fork/exec model: Uses a direct process model rather than client/server.
 Rootless support: Run containers without requiring root privileges on
the host.

3. Why Rootless Containers?


Rootless containers allow unprivileged users to create, run, and manage
containers without admin rights. Benefits:

 Enhanced security: Compromised container daemons or runtimes do not


yield host root access.
 Multi-user support: Multiple users can run containers on the same host
safely.
 Nested isolation: Run containers within containers without privilege
escalation.

From a security standpoint, running with fewer privileges reduces risk.


Podman achieves this by spawning container processes as child processes
of the user, with no central daemon.

4. Example: Using Rootless Containers with


Podman

4.1. System Requirements

 RHEL Enterprise Linux (RHEL) 7.7 or greater


4.2. Configuration
1. **Install dependencies:
2. sudo yum install slirp4netns podman -y
3. # Or install the Container Tools module:
sudo yum install @container-tools -y

o slirp4netns provides network connectivity in an unprivileged user


namespace.
4. Create a non-root user (e.g., rhel):-root user** (e.g., rhel):
5. sudo useradd -c "Red Hat" rhel
sudo passwd rhel
This new user is automatically configured for rootless Podman.

4.3. Connect as the User


Instead of su -, connect using a direct login method:
ssh rhel@localhost
This preserves the environment variables needed for rootless Podman.

4.4. Pull a RHEL Image


1. Pull the Universal Base Image (UBI):

podman pull [Link]/ubi7/ubi

2. Inspect the image:

podman run [Link]/ubi7/ubi cat /etc/os-release

3. List local images:

podman images
Note: Creating and running containers from these images can be covered
in a follow-up guide.

4.5. Verify Rootless Configuration


Check UID/GID mappings inside the user namespace:

podman unshare cat /proc/self/uid_map


This confirms that Podman is using subordinate user IDs without root.

5. Conclusion and Tips


 Storage location: Rootless container data resides under the user’s home
(e.g., $HOME/.local/share/containers/storage).
 Privilege isolation: Containers run with expanded UIDs/GIDs inside the
namespace but have no extra host privileges.
 Security best practice: Fewer privileges on the host reduce the attack
surface in multi-user environments.

Enjoy experimenting with rootless containers using Podman!

UPDATE 2025-03-10:
 Red Hat now provides a FREE LAB for this task

On Node2

Container Service
QUESTION #21:

 Configure a container to start automatically


 Use the container named myapp which we built in Lab Question #20.
 Configure the service to automatically mount the directory /opt/files to
container directory /opt/incoming. And the user
directory /opt/processed to container directory /opt/outgoing
 Configure it to run as a systemd service that should run from the existing
user andrew only
 The service should be named myapp and should automatically start a
system reboot without any manual intervention.

ANSWER #21:
[root@node2 ~]# mkdir /opt/files /opt/processed
[root@node2 ~]# chown andrew:andrew /opt/files /opt/processed
[root@node2 ~]# loginctl enable-linger andrew
[root@node2 ~]# ssh andrew@localhost
[andrew@node2 ~]$ podman run -d --name myapp -v /opt/files/:/opt/incoming:Z
-v /opt/processed/:/opt/outgoing:Z myapp
[andrew@node2 ~]$ podman ps

CONTAINER ID IMAGE COMMAND


CREATED STATUS PORTS NAMES
af03e63960ad localhost/myapp /usr/bin/run-http... 3
seconds ago Up 3 seconds myapp

 Let's see if Andrew has the right permissions to have Linger:


[andrew@node2 ~]$ loginctl show-user andrew
ID=1002
...
Timestamp=Sun 2023-04-23 09:54:45 IST
TimestampMonotonic=2614502454
RuntimePath=/run/user/1002
Service=user@[Link]
Slice=[Link]
Display=5
State=active
Sessions=5
IdleHint=no
IdleSinceHint=1682224288866742
IdleSinceHintMonotonic=3017922428
Linger=yes

 Next, we need to create a folder in the user’s directory


called ~/.config/systemd/user:

[andrew@node2 ~]$ mkdir -p ~/.config/systemd/user


[andrew@node2 ~]$ cd ~/.config/systemd/user

 We need to generate the service file in that directory:

[andrew@node2 user]$ podman generate systemd --name myapp --new --files


/home/andrew/.config/systemd/user/[Link]
[andrew@node2 user]$ systemctl --user daemon-reload

 Next, stop the running container:

[andrew@node2 user]$ podman stop myapp

 Now start & enable the service:

[andrew@localhost ~]$ systemctl --user enable --now [Link]

 SUCCESS!!

Additional Information:
Syntax:

$ podman run -v <src>:<dst>:Z <image>

# Add port to the firewall


firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload

BONUS: Alternate lab from Red Hat:


yum install -y podman
mkdir -p ~/.config/containers/systemd/

cat << EOF > ~/.config/containers/systemd/[Link]


[Service]
Restart=always

[Container]
ContainerName=httpd
Image=[Link]/library/httpd
Label="[Link]=registry"
Environment=TZ=America/Vancouver
Environment=VERSION=docker
Volume=[Link]:/usr/local/apache2/htdocs:Z
PublishPort=8080:80/tcp

[Install]
WantedBy=[Link]
EOF

cat << EOF > ~/.config/containers/systemd/[Link]


[Volume]
User=garfield
Group=garfield
EOF

systemctl --user daemon-reload

systemctl --user start [Link]

podman ps

systemctl --user status httpd --no-pager

systemctl --user stop httpd

curl [Link]

Add new remote repository for


YUM
Question:
Add additional repository for YUM with name my_custom_repo which can
be found via URL [Link]

Answer:

 YUM repositories are configured mostly in the file /etc/[Link]. We can


see the total contents of this file with added formatting using command (if
it is not installed You can find it in the yum-utils package):

yum-config-manager
 Among the properties listed in this file is reposdir which specifies
(by default) paths to folders which are being scanned for files
containing information about repositories. In my case the existing
folder is /etc/[Link].d.
 We create a config file in this folder - by convention the suffix of
these files is .repo.

vi /etc/[Link].d/my_custom_repo.repo
# and we enter in editor below content
[my_custom_repo]
name=my_custom_repo
baseurl=[Link]
enabled=1

 Suppose the contents of the repo file is too hard to remember, you can
alternatively use yum-config-manager to add a new repo and rename it
later.

yum-config-manager --add-repo="[Link]

 This will create a new repo file


in /etc/[Link].d/local.repo_rhel7.repo with the following contents.

[local.repo_rhel7]
name= created by dnf config-manager from [Link]
baseurl=[Link]
enabled=1

 You can then edit the file contents and rename the file as per you need. In
our content, it would be:

[my_custom_repo] # renamed
name= my_custom_repo # renamed
baseurl=[Link]
enabled=1

 Make sure that repository is seen by YUM:

yum repolist | grep my_custom_repo


* or other (which is more readable)
yum-config-manager my_custom_repo
Note: You might encounter gpg check failures when you add a new repo,
so skip gpg checks in that case append to the new repo file the following.

gpgcheck=0

Assign SELinux context


Question:
Assign the same SELinux contexts used by the home directories to
the /xfs directory permanently.

(scroll down for an answer)


Answer:

 For interacting with context in SELinux we need a command that is not


available by default on RHEL. Therefore we have to install it. First we find
out what is the package name we need:

yum whatprovides */semanage

 On my system (CentOS) it was policycoreutils-python with


additional architecture/version suffix. This is what must be installed
using YUM.
 There is a command called chcon - however its usage is not advised
(besides restoring root password)!
 Finding proper context to be applied is usually the most tricky part.
However it is good to remember that almost every Linux command
that is used to list files/folders/processes/etc has -Z flag, which will
show the SELinux context of specified item. So we can use:

ls -Z /home
which on my computer produces the output below:

drwx------. chlebik chlebik unconfined_u:object_r:user_home_dir_t:s0


chlebik

 Context is the one with _t suffix. The way to assign it to


mentioned /xfs target folder is this:

semanage fcontext -a -t user_home_dir_t "/xfs(/.*)?"

 However above command only assigns this context to the policy. In


order to write it to the filesystem we need to invoke:

restorecon -R /xfs

Create compressed archive


Question:
Create the archive file /root/[Link] for /usr/local compressed by gzip.
Answer:

 The command is simple and straightforward (just remember that -f flag


must be the last one as the file name follows it):

tar -cvzf /root/[Link] /usr/local

User creation with specific


properties
Question:
Create two users: john with uid/gid equal to 2000, password 12345678
and davis with uid/gid equal to 3000, password 87654321.
Make davis' password validity stopping in one month.

Answer:

 The best command for user creation and editing are these starting
with user - so useradd and usermod.

useradd -u 2000 john


passwd john
# here provide password for john

useradd -u 3000 davis


passwd davis
# here provide password for davis

 Right now is the time to change validity of davis account. On my system


(CentOS) I've run:

[root@centos1 ~]# chage -l davis


Last password change : Sep 14, 2019
Password expires : never
Password inactive : never
Account expires : never
Minimum number of days between password change : 0
Maximum number of days between password change : 99999
Number of days of warning before password expires : 7

 Given that we know the current date we can set expiry date manually by
copying the following from the chage man pages:
man chage
chage -E $(date -d +30days +%Y-%m-%d)

Additional comment:
Using "man chage" and scrolling down a bit you can copy and paste the
command above without memorizing it and just simply paste the number
of days you want to add until the account expires. Remember there is a
difference between password expiration and account validation. It is
usually better to expire password and make user not being able to log into
the system or disable the user, rather than deleting it.

usermod command is also used for adding/removing users to the group


(groupmod command does not do that)

Trying to create user with already taken UID will result in an error.

During user's creation with useradd command the structure of home


direcotry is taken from /etc/skel folder.

Enable SELinux in enforcing


mode
Question:
Enable SELinux in enforcing mode

Answer:

 Make sure that SELinux is enabled. This setting can be changed only via
reboot! Issue the command getenforce and check what is the status
of SELinux. If You see Disabled then edit the
file /etc/sysconfig/selinux and in a proper line
change disabled to enforcing.
 Reboot the system
 Again check SELinux status using command getenforce

On Node2

Setting up a Grub Password to


prevent bootloader modification
QUESTION #23:
Set a user password on the Grub bootloader to prevent the root password
from being reset.

(scroll down for an answer)


ANSWER #23:

 Set the Grub bootloader password and then reboot:

[root@node2 ~]# grub2-setpassword


Enter password:
Confirm password:
[root@node2 ~]# init 6

 To rollback the Grub bootloader password (make it blank):

[root@node2 ~]# find /boot -name "*[Link]" -exec sed -i


'/GRUB2_PASSWORD/d' {} \;
[root@node2 ~]# init 6

That will effectively blank the password and you will


simply have to run init 6 to reboot.

 SUCCESS!!

On Node2

Setting up a Grub Password to


prevent bootloader modification
QUESTION #23:
Set a user password on the Grub bootloader to prevent the root password
from being reset.

(scroll down for an answer)


ANSWER #23:

 Set the Grub bootloader password and then reboot:

[root@node2 ~]# grub2-setpassword


Enter password:
Confirm password:
[root@node2 ~]# init 6

 To rollback the Grub bootloader password (make it blank):

[root@node2 ~]# find /boot -name "*[Link]" -exec sed -i


'/GRUB2_PASSWORD/d' {} \;
[root@node2 ~]# init 6

That will effectively blank the password and you will


simply have to run init 6 to reboot.

 SUCCESS!!

Install new kernel and make it


default
Question:
Install the kernel from the source [Link] The following
criteria must be met:

 installed kernel will be the default one when system boots


 previous kernel is still available

(scroll down for an answer)


Answer:
 In order to get new kernel from specified link You should add this
link as a repository that can be seen by YUM. The procedure for
adding a repository was described in question 016 so I won't be
repeating myself here.
 After the repo is added, enabled and visible by YUM the command
is:

yum install kernel


 Mentioned criteria are actually not a problem as this is the default
behaviour - the kernel is not itself updated but new version is
installed. By default system saves previous 4 versions of kernel on
the disc.
 To make sure what is the default kernel being loaded by boot-loader
we use a command grubby:

grubby --info=ALL
that will list all installed kernels (the one with index 0 will be loaded by
default). If it is not the kernel You just installed You can change it by
issuing:

grubby --set-default-index INDEX_OF_NEW_KERNEL


and reboot the system to see if the changes apply

Reduce the size of existing


logical volume
Question:
Reduce the size of existing logical volume by 400MB.

(scroll down for an answer)


Answer:

 First we list existing logical volumes:

lvdisplay

 We should get the /dev...* link to our logical volume. That is step one. In
order to shrink the existing size of logical volume it requires unmounting it
to perform this operation:

umount /MOUNT_POINT

 It came the time to resize our logical volume:

lvreduce -r -L -400M /dev/LINK_TO_LVM

 Now we just remount the volume again and check if everything as it


should be:

mount -a
lvdisplay
Set new default system level
Question:
Set the default target to boot into X Window level (previously level 5).

(scroll down for an answer)


Answer:

 It is simple task configuring systemd properly:

systemctl set-default [Link]

 We can also check if it succeeded with:

systemctl get-default

Additional comment:
Here is the list of all targets in systemd:

 0 [Link]
 1 [Link]
 2 [Link]
 3 [Link]
 4 [Link]
 5 [Link]
 6 [Link]

Some time ago a file /etc/inittab was used to specify default system level
however now it is deprecated and does not work.

Configure a block device to use


VDO on LVM
QUESTION #22 - VDO on LVM
Create a VDO named vdo1 of size 50Gb and mount it at /vdo_m.

 This may or may not be on the actual exam, but you may still attempt it
anyway.
(scroll down for an answer)
ANSWER #22:
 VDO is a way to provide deduplication and compression of data on
the disc. Worth read material can be found here.
 First, attach storage to your physical or virtual machine. Then, run:

lsblk
yum -y update
init 6

 After reboot, install lvm2, vdo, and kmod-kvdo. Then create the volume
group:

yum -y install lvm2 vdo kmod-kvdo

systemctl enable --now vdo


df -h

 In this example DexTutor uses /dev/nvme0n3 as the target device. You can
use whatever comes up that's not mounted in df -h:

pvcreate /dev/nvme0n3

 Next create the volume group VG1 using vgcreate:

vgcreate VG1 /dev/nvme0n3

Vgs
 Run “lvcreate” specifying the type as “vdo” and give it name “VDO1”:

lvcreate --type vdo --name VDO1 --size 5GB --virtualsize 50GB VG1

 You can run lsblk to check your work:


 From here you need to format the filesystem according to what the
exam states:

[Link] -K /dev/nvme0n3
# or
mkfs.ext4 -E nodiscard /dev/nvme0n3

 NOTE: when creating VDO we do not want to discard blocks when


making the filesystem. So use proper switch (see man pages) for
specific type of filesystem being created.
 After this make sure to refresh registers:

udevadm settle

 The last step is to mount the VDO logical volume and it needs to be
persistent in /etc/fstab:

mkdir /vdo_m
vim /etc/fstab
/dev/VG1/VDO1 /vdo_m xfs defaults 0 0
:wq

 It should look like this:


SUCCESS!!

Additional comment:

 The commands to check status and size of VD

You might also like