DEV Community

Nnamdi Felix Ibe
Nnamdi Felix Ibe

Posted on

100 Days of DevOps, Day 5: SELinux Isn't Your Enemy, and GP3 Is Your Default

Most people meet SELinux for the first time when something breaks, and their first move is to switch it off. I get the reflex. But "disabled" is the laziest of the three options SELinux hands you, and Day 5 of this challenge is where that finally clicked for me.

Two tasks today, one on Linux and one on AWS. Install and configure SELinux on a RHEL-style box, and create a GP3 EBS volume from the AWS CLI. Both look like one-liners. Both hide a second layer that only shows up when you slow down and ask why. The tasks come from the KodeKloud Engineer platform if you want to follow along on the same setup.

SELinux: three modes, and why "off" should be last

SELinux stands for Security-Enhanced Linux, a mandatory access control layer baked straight into the kernel. Regular Linux permissions decide what a user is allowed to do. SELinux determines what a process is allowed to do, even when the user technically has the necessary permissions. That second gate is the entire point.

Picture a web server that gets compromised. With standard permissions alone, the attacker inherits whatever the web server user can touch. With SELinux in enforcing mode, that same hijacked process is boxed into exactly the files and ports its policy allows, so it cannot wander off across the filesystem. That is a security layer worth understanding before you rip it out.

Here are the installation steps. On RHEL, CentOS, Rocky and AlmaLinux, these packages are usually present already, but the task wanted it explicitly:

# Install the SELinux packages
sudo yum install selinux-policy selinux-policy-targeted policycoreutils
Enter fullscreen mode Exit fullscreen mode

policycoreutils is the package that gives you sestatus, setenforce and the rest of the tooling. Next, set the mode permanently by editing the config file:

# Set the mode permanently
sudo vi /etc/selinux/config
# change SELINUX=enforcing to SELINUX=disabled
Enter fullscreen mode Exit fullscreen mode

This file is the source of truth for what the box boots into. The task asked for disabled, so that is what went in. Then confirm the live status:

# Check the current status
sestatus
Enter fullscreen mode Exit fullscreen mode

Now the part the one-liner hides. SELinux has three modes, and they are not interchangeable:

  • enforcing: rules are applied, violations are blocked and logged. This is what you want in production.
  • permissive: nothing is blocked, but every violation is logged. This is your debugging mode.
  • disabled: SELinux is off. No enforcement, no logs, no safety net.

When a service suddenly cannot read a file it clearly owns, the instinct is to jump straight to disabled. Fight it. Flip to permissive instead, reproduce the problem, and read the logs it generates. You get your answer without tearing out the whole security layer. Plenty of quickstart guides tell you to disable SELinux just to remove a variable, and that is fine on a throwaway lab box. It is a bad habit to carry into anything real.

Two things will catch you here.

First, switching to or from disabled needs a reboot. Editing the config file does not change the running mode on its own. Before you reboot, sestatus still reports the old state, which fools a lot of people into thinking the command failed.

Second, going from disabled back to enforcing is not free. The filesystem has to be relabeled so every file gets its SELinux context back. You trigger it like this:

# Relabel the whole filesystem on the next boot, then reboot
sudo touch /.autorelabel
sudo reboot
Enter fullscreen mode Exit fullscreen mode

Skip that step, and you can boot into a machine where half your services refuse to start, which is a miserable way to learn what relabeling actually does.

GP3: the volume type you should default to

Over on AWS, the task was to create a GP3 EBS volume in a specific availability zone and tag it so you can find it later. One command does it:

# Create a 2 GiB GP3 volume in us-east-1a
aws ec2 create-volume \
  --availability-zone us-east-1a \
  --volume-type gp3 \
  --size 2 \
  --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=my-volume}]'
Enter fullscreen mode Exit fullscreen mode

Reading it left to right:

  • --availability-zone: a volume lives in exactly one AZ. It cannot cross zones, ever.
  • --volume-type gp3: the current-generation general-purpose SSD.
  • --size 2: the size in GiB, not GB. AWS measures and bills EBS in gigabytes, so 2 means 2 GiB.
  • --tag-specifications: tags the volume at creation time so you are not later hunting for a nameless vol-0a1b2c3d.

That tag block is the fiddly part. The ResourceType=volume prefix is required, and the quoting matters, so copy it carefully. Then verify the volume exists:

# Confirm it was created
aws ec2 describe-volumes --filters "Name=tag:Name,Values=my-volume"
Enter fullscreen mode Exit fullscreen mode

The output shows the volume with a State of available, meaning it is created but not yet attached to anything.

So why default to GP3 over the older GP2? Performance you can actually reason about. GP3 gives every volume a flat baseline of 3,000 IOPS and 125 MiB/s of throughput no matter how small it is, and it lets you dial those numbers up independently when you need more (per the AWS EBS documentation).

GP2 ties performance to size. It gives you 3 IOPS per GiB, so a small GP2 volume is also a slow one, and the only way to speed it up is to make it bigger. GP3 breaks that link and usually costs less per GiB on top of it. For most general workloads, GP3 is the sensible default, which is exactly why AWS made it the default.

One catch, and it rhymes with the SELinux lesson: placement matters. Because this volume is pinned to us-east-1a, you can only attach it to an EC2 instance sitting in that same zone. Get the AZ wrong, and the volume is dead weight until you snapshot it and rebuild it elsewhere. Check your instance's AZ before you create the volume, not after.

Creating the volume is only step one. The real next move is attaching it with aws ec2 attach-volume, then formatting and mounting it on the instance. The task stopped at creation, though, so I will keep this honest and stop there too rather than pretend I did more.

The actual lesson

Both tasks were technically a single command. Both had a second layer that only appears when you ask why instead of copying the line and moving on. SELinux is not a switch to flip off; it is a set of modes with a purpose. GP3 is not a random SSD; it is a deliberate default with numbers behind it. That gap, between running a command and understanding it, is the whole difference between collecting completed tasks and owning the skill.

So here is the choice I would put to you if you are learning this too. Would you rather rack up a hundred green checkmarks you cannot explain, or ten you could rebuild from memory and defend in an interview?

Day 5 down. Ninety-five to go.

Top comments (0)