First Time Configuration for RHEL9/OEL9

A disclaimer: I use OEL for server-use when I can. A long support window, an enterprise environment, and yes, a very low rate of changes within the life cycle of the operating system makes it a very good candidate to hold services I do not want to fuss around, correcting configuration files on update or chasing some hidden change. The downside is that I don’t get the cutting edge technologies – and I can live with that quite well.

If I do want newer technologies than provided by the vendor, I can always use specific repositories for specific software packages. If done selectively, I can have a combination of old-and-new which is my exact match. With “older” components for the main parts, and a cutting-edge fine-grained components.

My adoption rate for OEL version 9 is slow, unfortunately, and it is based, mainly, on the adoption rate of 3rd party software components and their OS certification policy. Oracle RDBMS, for example, is a major driver in my adoption rate, since a noticeable part of my job is preparing systems for Oracle RDBMS or Oracle Grid Infrastructure based on Linux (you can already guess which Linux it is, right?).

In this post, I will discuss some of the initial tasks you might want to consider doing initially on a newly installed or newly migrated OEL9. This may appear redundant to you, however, it can be used as a grocery list of tasks you can select out of, when setting up a new system. With the relatively new technologies I was able to ignore up to now, and their updated configuration interfaces, this should provide me (and maybe you) a good starting point to harden and ensure your systems are well within the tolerable configuration directives, or as a single point of knowledge for the common tasks at their new and updated command interface.

Let’s get to the list of actions:

Network Settings

In the past, editing /etc/sysconfig/network-scripts/ifcfg-<ifname> was enough. Now, this file does not exist, and while we might be able to use some legacy interface to return it to life, this post (as well as my process) is about moving forward, not bringing the past back.

Using ‘ip a’ command, identify the name of the interface.

If no specific changes performed earlier, by the command

nmcli con show

the existing network interface can be seen. In my case, the network interface is enX0. My output is:

NAME  UUID                                  TYPE      DEVICE 
enX0  6c395e21-eb61-3676-aef2-0e2acb177261  ethernet  enX0 

To set it up, do the following:

nmcli con mod enX0 ipv4.gateway ipv4.addresses ipv4.method manual ipv4.dns ""
nmcli con up enX0

Now, run ‘ip a’ and ‘ip r’ to verify your settings are correct.

Host Name

This was already introduced and enforced in previous versions, however, it’s a good idea to recapture that. The command is ‘hostnamectl’ and it can be used like this:

hostnamectl set-hostname

A manual modification can take place in the file /etc/hostname, but manually editing this file will apply only after reboot.

Automatic Updates

I am a great fan of automatic updates. Unfortunately, I do not enforce reboots on kernel updates (nor do I use the in-place kernel patching mechanism, such as the ones provided by Oracle or kernel-care), however – at least let them be updates.

To do so, you will need to install the package “dnf-automatic.noarch”, then edit /etc/dnf/automatic.conf (I enable the “apply_updates” flag) and then enable the service dns-automatic-notifyonly.timer

systemctl enable --now dnf-automatic.timer

Performance Monitoring

I like to use ‘sysstat’ package. I find that the information kept in /var/log/sa can be very useful for analysing events and past misbehaviour. If you do not want to run the (local, on your desktop) tool ‘kSar‘, you can gain some wonderful insights from the online Sar analysis tool. There is a problem, though – the automatic performance collection interval is once every 10 minutes, which is not enough. My experience shows that once every minute is good enough to get a very good idea of the system’s load, while not overloading it. To make these modifications, you need to install the package sysstat first:

dnf install -y sysstat

and then, edit the unit file like this:

mkdir -p /etc/systemd/system/sysstat-collect.timer.d/
cat << EOF > /etc/systemd/system/sysstat-collect.timer.d/override.conf
Description=Run system activity accounting tool every minute

Then, just enable it:

/usr/bin/systemctl enable sysstat-collect.timer

Remote Login Using SSH Keys Only

This is easy – you do not want to login to a system without SSH keys, especially if it is located on a public-access area. You will both need to copy your keys to the system (not covered here) and modify /etc/ssh/sshd_config file to set

PermitRootLogin prohibit-password

Following that, restart sshd service for the changes to take effect.

Add a User

Add a user through which you should normally work, and make sure it has SSH key, and not a password. Passwords are bad.


Fail2ban is a tool to prevent (or at least – attempt to block) remote IP addresses attempting brute-force logins to your system. If your system is on a public network, it is not a bad idea to set it up. It was easy to do for OEL8, however OEL9 EPEL repository does not provide these packages, and the ones provided by OEL8 EPEL repository are incompatible to the Python ABI (3.9 present vs. 3.6 required).

In the FedoraProject EPEL, the relevant packages can be found. In order to install it, run the following commands:

dnf install
dnf install -y fail2ban fail2ban-firewalld fail2ban-server

You can decide if you want this repo enabled (meaning – future updates might use it) or not. I have decided to leave it enabled.

To configure fail2ban, you should copy the file /etc/fail2ban/jail.conf to /etc/fail2ban/jail.local (because there is a chance that the author of this RPM is unfamiliar with the configuration file directives), and edit it to include several interesting objects (your milage might change):

bantime  = 36h # was 10m
maxretry = 3   # was 5

Find in this file the section called “sshd” and add a line to it “enabled = true”:


# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
# normal (default), ddos, extra or aggressive (combines all).
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
#mode   = normal
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
enabled = true

Now, sshd should be monitored, and the default interface – firewalld (if you have modified it – change the interface. Find information about it) should be the one to use. To complete this task, just enable the service:

systemctl enable --now fail2ban

To test fail2ban, you can run either “fail2ban-client status sshd”

# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed:	2
|  |- Total failed:	16
|  `- Journal matches:	_SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned:	2
   |- Total banned:	2
   `- Banned IP list:

Or check your firewalld if you are using it (default setup for OEL9):

# iptables-save | grep f2b-sshd
:f2b-sshd - [0:0]
-A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd
-A f2b-sshd -s -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -s -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -j RETURN

Additional Tasks

There are some additional tasks I do not cover here. Firewall configuration, SELinux (enable/disable/fine-tune), 3rd party software installation and more. It’s not that these tasks are not required, it’s just that there is no one-size solution here. This should provide a good enough list to begin with.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.