RHCE - RHEL7 - Part 1

System Configuration and management

This is the first in a three part series covering the objectives for the Red Hat Certified Engineer (RCHE, EX300) exam.

Each part will follow the objectives as they have been outlined by Red Hat.

Aggregated network links

The full objective is: Use network teaming or bonding to configure aggregated network links between two Red Hat Enterprise Linux systems

Official Red Hat Documentation

Using VirtualBox, we can configure two machines to connect to each other with several network configurations. In this setup I'll be using a 'host-only network'. With two NICs in the VM they are named enp0s3 and enp0s8 which will be the "ports" which will be teamed.

I have to modify the configuration files for these interfaces. I use a "golden image" which I clone to make the practice devices to I have make sure to ignore the configured MAC address (since it changes from the one configured during installation when we clone). I've shown which lines I modified, the rest can remain as the default.

[root@red ~]# cd /etc/sysconfig/network-scripts
[root@red network-scripts]# cp ifcfg-enp0s3 ifcfg-enp0s8
[root@red network-scripts]# vim ifcfg-enp0s3
NAME=enp0s3 (or enp0s8 depending on which interface config we're using)
[root@red network-scripts]# ifdown enp0s3
[root@red network-scripts]# ifdown enp0s8

Now we can actually configure our team:

[root@red ~]# nmcli connection add type team ifname Team0
[root@red ~]# nmcli connection add type team-slave con-name Team0-port1 ifname enp0s3 master Team0
[root@red ~]# nmcli connection add type team-slave con-name Team0-port2 ifname enp0s8 master Team0
[root@red ~]# nmcli connection up Team0-port1
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/4)
[root@red ~]# nmcli connection up Team0-port2
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/5)
[root@red ~]# vim /etc/sysconfig/network-scripts/ifcfg-team-Team0 

Setting the IP address statically this way requires us to restart the system in order for the team to actually have the address assigned. At the time of writing I am not aware of any way to set the ip address without rebooting besides doing this command:

[root@red ~]# ip addr add dev Team0

From here, we can ping other devices in the nework showing that the team has been created successfully.

Configuring the runners (to change from the default roundrobin) will require information from the relevant man page:

[root@red ~]# man 5 teamd.conf

Configure IPv6 addresses and perform basic IPv6 troubleshooting

Configuring IPv6 addresses follow the same procedure as configuring IPv4 addresses. We would edit the files in /etc/sysconfig/network-scripts and set the address we want there.

Route IP traffic and create static routes

There is a section in the documentation on configuring static routed using the command line. The relevant man page to get information on configuring static routes will be ip-route. Thanks to Will Twomey who helped me figure out the static networking aspect of this section.

man ip-route

An important thing to note is how to make changes persistent:

Static routes set using ip commands at the command prompt will be lost if the system is shutdown or restarted. To configure static routes to be persistent after a system restart, they must be placed in per-interface configuration files in the /etc/sysconfig/network-scripts/ directory.

For this example, I'll be using three devices and 2 subnets. I'll have one device in each subnet with the third device acting at the router between them. This is how the network will be configured:

router  both    and

To configure the interfaces we'll edit the files within /etc/sysconfig/network-scripts/ and provide the following information:


For the static routes themselves we can create files in /etc/sysconfig/network-scripts/ named route-enp0s3 with the routes listed with the following format: via

This is how alpha was configured, we'd adjust the information for each system. Also, the router is going to have an interface in each network so I had files ifcfg-enp0s3 and ifcfg-enp0s8 on that system.

With just this much we can have alpha and beta ping the router successfully and the router can ping both but the systems can't ping across the router yet.

We'll have to turn routing 'on' at the router by modifying a kernel parameter. We'll have to add the following to the /etc/sysctl.conf file

net.ipv4.ip_forward = 1

Now we can start configuring the static routes. First, I want alpha to know how to get to the network. It will have to go through the routers interface on the network. So:

ip route add via

From here we can ping the routers interface in that network, but pings will fail if we try to reach betas interface. This is because the packets are sent to beta but beta doesn't know how to get those packts back to where they came from. We'll now have to configure the static route on beta:

ip route add via

Now pings between the two systems work as expected since they both know how to reach each other.

We can check the system configured on the system by using the following commands:

ip route

Using firewalld

The full objective is: Use firewalld and associated mechanisms such as rich rules, zones and custom rules, to implement packet filtering and configure network address translation (NAT)

The Fedora project has a great document on the subject of firewallD which I'll be following along with here.

Let's start with the most important command for an exam: where to get quick help:

[root@firewall ~]# firewall-cmd -h

First, let's see what firewallD is up to:

[root@firewall ~]# firewall-cmd --state

firewallD uses zones to configure rules based on levels of trust, let's see what zones firewallD is working with:

[root@firewall ~]# firewall-cmd --get-zones
block dmz drop external home internal public trusted work

We can use the --list-all-zones command to get an overview of all the zones. In this example I'm only showing the config for the block zone but it shows you the type of things that are available for configuration for the zone.

[root@firewall ~]# firewall-cmd --list-all-zones
  masquerade: no
  rich rules: 

So let's get down to some actual work. I'll set up apache and we'll work through getting it opened and available.

[root@firewall ~]# firewall-cmd --add-service=http

That's it! Without specifying a zone, it will automatically use the default zone, in my case the public zone.

We use the --permanent option to make sure that the rules we set will be available after we reboot. Note:

The permanent options are not affecting runtime directly.

The fedoraproject site also has some documentation for information pertaining to 'rich rules'. Essentially 'rich rules' is a syntax that allows us to describe iptables rules in a structured sort of way.

[root@firewall ~]# firewall-cmd --add-rich-rule='rule protocol value='ah' accept'

In this example we are adding a protocol rule which applies to the 'authentication header' protocol.

The scope of the rich rules syntax is a bit much to cover here but there is a man-page for it which provides several examples and is actually easy to use.

[root@firewall ~]# man firewalld.richlanguage

As for NAT, SSN Network has a great video on youtube on the subject. In short you are going to either add an interface to the external zone where masquerading is enabled by default or adding the masquerade option to a zone you would like to add NAT to.

Use /proc/sys and sysctl to modify and set kernel runtime parameters

We can use /proc/sys or /etc/sysctl.conf to make changes to the kernel runtime parameters.

For example, if we cat out the contents of the /proc/sys/net/ipv4/ip_forward file we can see what forwarding for this system is set to 0 (off) or 1 (on).

We can change the value to what we want in this file or we can set it in the /etc/sysctl.conf file this way:

net.ipv4.ip_forward = 1

Notice that the name follows the directory structure within /proc/sys.

Configure a system to authenticate using Kerberos

You'll need the authconfig package which will give you the authconfig-tui program which makes configuring a system to use kerberos very, very easy.

yum install -y krb5-workstation pam_krb5
domain PEQUENO.in
kdc krb.pequeno.in
admin krb.pequeno.in
# kinit test1
ssh test1@krb.pequeno.in

Configure a system as either an iSCSI target or initiator

The full objective is: Configure a system as either an iSCSI target or initiator that persistently mounts an iSCSI target

In the version of this exam for RHEL 6 the objective was to configure an iscsi initiator but in this version it seems like you should be able to do both. The good news is that configuring an iscsi target is actually easier since we now use a tool from Datera called targetcli. I'll be following this guide.

The important thing to note is that we need to set attribute authentication=0 and set attribute generate_node_acls=1 to allow us to use the target without having to use authentication. This isn't the safest option but it will help when practicing.

yum -y install targetcli 
[root@iscsi ~]# mkdir /iscsi_disks
[root@iscsi ~]# targetcli
targetcli shell version 2.1.fb34
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.

/> cd backstores/fileio

/backstores/fileio> create disk01 /iscsi_disks/disk01.img 5G
Created fileio disk01 with size 5368709120

/backstores/fileio> cd /iscsi 
/iscsi> create iqn.2014-11.in.pequeno.iscsi:tgt1
Created target iqn.2014-11.in.pequeno.iscsi:tgt1.
Created TPG 1.

/> cd iscsi/iqn.2014-11.in.pequeno.iscsi:tgt1/tpg1/

/iscsi/iqn.20...csi:tgt1/tpg1> set attribute authentication=0
Parameter authentication is now '0'.

/iscsi/iqn.20...csi:tgt1/tpg1> set attribute generate_node_acls=1
Parameter generate_node_acls is now '1'.

/iscsi> cd /portals 

/iscsi/iqn.20.../tpg1/portals> create 
Using default IP port 3260
Binding to INADDR_ANY (
Created network portal

/iscsi/iqn.20.../tpg1/portals> cd ../luns 

/iscsi/iqn.20...gt1/tpg1/luns> create /backstores/fileio/disk01 
Created LUN 0.

/iscsi/iqn.20...gt1/tpg1/luns> exit
Global pref auto_save_on_exit=true
Last 10 configs saved in /etc/target/backup.
Configuration saved to /etc/target/saveconfig.json

Now we can configure the initiator:

[root@initiator ~]# yum install iscsi-initiator-utils -y
[root@initiator ~]# iscsiadm -m discovery -t sendtargets -p iscsi.pequeno.in,1 iqn.2014-11.in.pequeno.iscsi:tgt1
[root@initiator ~]# iscsiadm -m node -T iqn.2014-11.in.pequeno.iscsi:tgt1 -p iscsi.pequeno.in -l
Logging in to [iface: default, target: iqn.2014-11.in.pequeno.iscsi:tgt1, portal:,3260] (multiple)
Login to [iface: default, target: iqn.2014-11.in.pequeno.iscsi:tgt1, portal:,3260] successful.

From here, we can treat the target as a normal disk and add it to our /etc/fstab for persistant mounting.

Produce and deliver reports on system utilization (processor, memory, disk, and network)

I think the idea here is to get familiar with the sar command to generate reports on system utilization. A very quick way to cover all your bases is to get sar to give you everything (-A) and dump it into a file:

[root@sysconfig #] sar -A > system-info.txt

Generally, get familiar with sars flags. How you produce reports and what you report on will depend on how they ask the question on the exam.

In Michael Jang's book he also suggests to use sadf to produce reports. sadf works similarly to sar but it produces output in CSV so they can be easily imported into other data analysis tools.

Use shell scripting to automate system maintenance tasks

Again, how you solve this problem depends on exactly what they ask you to do on the exam. But let's make up some scenarios that will demonstrate how we'd be able to do some common administration tasks with some scripts.

Example 1

In this example I've created a short python script that will create 10 files randomly named and of a random size between 1MB and 10MB. I'll tell cron to run this a few times to generate a lot of files.

import random
from subprocess import call
import uuid
import os


for i in range(1, 11):
    file_size = str(random.randint(1, 10))
    file_name = str(uuid.uuid4())
    call("dd if=/dev/zero of=" + file_name + " bs=1M count=" + file_size + " 2> /dev/null", shell=True)

Now we have a directory full of files of various sizes. Let's use bash to go into the directory and identify files smaller than 2MB:

[root@script ~]# cat cleanup.sh 
cd /root/manyfiles

# 2MB in bytes

for i in $(ls); do
  FILESIZE=$(wc -c "$i" | cut -f 1 -d ' ');
  if [[ $FILESIZE -le $MINFILESIZE  ]]; then
    echo $i
[root@script ~]# ./cleanup.sh 

Example 2

In this example we'll have bash tell us how many httpd processes are running and put them into a file to be served by Apache

[root@script ~]# cat httpd.sh 
echo "There are" $(ps aux | grep -c httpd) "httpd processes currently running" > /var/www/html/proc.html

Now we can just have cron run this every minute and when we go to http://powertra.in/proc.html (for example) we will see how many http process were running when the script was called.

Fork me on GitHub