In this lesson,
we'll explore how we can enforce mandatory access control
with the help of the Se Linux security module.
Now, Red Hat and Sento operating systems have Se Linux enabled by default.
But on
Ubuntu, a different security module called app Armor is used by default
whenever we end up on a system that was set up by other people. If we need Se Linux,
we should first check if it's already
configured before we attempt to install anything.
We'll explore how to check the security module status later in our lesson.
But since we know our system doesn't have Selinux,
let's see how we can get it started from scratch on Ubuntu.
Since app Armor is enabled by default, first, we'll have to disable that
using two security modules at the same time
might lead to conflicts or unexpected results.
So first we need to stop the App Armor service,
then we disable App Armor from automatically starting up when the system boots
next to get started with Se Linux, we install these two packages.
Se Linux basics and auditd.
The Se Linux package will pull in all the Se
Linux utilities we'll need and some default security policies.
The audit D package contains the audit daemon.
This is the utility that will log certain system events
and help us build additional Se Linux security policies,
customized for our system
to check if Se Linux is enabled on our system, we can run se status
and as expected, it's disabled in our case
to enable Se Linux on a system. A couple of things need to be set up first.
The bootloader needs to be configured to tell
the Linux kernel to load the security module.
Also, every file on the system needs to be properly labeled
because Se Linux uses labels for everything to decide
what a certain object is allowed to do.
If we take a look at our system.
Now we'll see that Se Linux labels are currently missing
question marks appear instead of proper security labels.
The good thing is that Ubuntu has a utility that
can go through all the steps necessary to enable Se Linux
and re label the file system.
So the command that we need to run is pseudo
E Linux activate.
And we can see it modified the grub bootloader to instruct the
Linux kernel to load the Se Linux module at boot time.
Let's look at some of the settings passed to the bootloader.
This line instructs the bootloader to pass an argument to the Linux kernel,
which in turn will load Se Linux.
And if we take a look at the root file system telling Ls to show us the hidden dot files,
we'll see a special file called auto re
label
that instructs Se Linux to re label every file
with the property security labels when we reboot.
So let's do that.
The relabeling process takes a while.
The more files there are on a file system, the longer it's going to take.
And after the reboot, the bootloader is configured to wait for 30 seconds.
This is a measure to help us step in and
fix the boot process in case something went wrong.
So for the first boot, after enabling Se Linux is successful,
this delay for the bootloader is removed.
So Linux will boot normally the next time
and now we can SSH back in and things should be different.
First of all, the files should have proper security labels.
And if we check the status of Se Linux, again,
we will see different output this time.
Notice that the Se Linux status mentions that our security model is enabled.
But under current mode, we can see that it's in a permissive state.
That's because Se Linux can run in two modes, permissive or enforcing.
We'll see what each one does.
Now,
another way to check the CF Selinux is running in
permissive or enforcing mode is to use the get enforce command
when Se Linux is enabled.
But in permissive mode, it's not enforcing security rules.
It's just observing every action on our system passively.
We can think of this as sort of a learning mode.
It's not disallowing any action,
but it logs what its current security policy would normally deny
and it logs these potential security violations in the audit log.
That's why we installed the audit daemon earlier.
Now, in a real scenario, we'd have to run se Linux in permissive mode for a while.
We can think of this as training it.
We let it observe all of the typical actions that happen on this system every day.
Once we think it observed everything, we can go to the next step,
creating a security policy, custom tailored for our system.
At this point.
If we were to switch Se Linux to enforcing mode,
it wouldn't even allow us to log in through SSH.
But because it's in learning mode,
the audit log recorded the actions it observed when we logged in,
we can take a look at what Se Linux recorded in the audit log with this command.
The dash dash all option tells the audit two Y command to show all logged events,
we'll pipe the output to less so that we can scroll through it and search for text.
Let's search for parts that contain the text. SSH.
We'll see many matches here like this one
note that the part mentioning AB C colon denied
AB C is short for access vector cache.
This simply shows that the action that Se Linux observed
here would normally be denied by the current security policy.
Also notice the SSH D underscore T label,
basically a process with this label tried to do something that is not permitted.
But since se Linux is in permissive mode, the action was logged but not disallowed.
Also notice that something called a type enforcement rule is
disallowing this for the SSH D underscore T context.
And a tool called audit two allow is recommended
to fix this and we'll get to that soon.
Let's exit from this log.
And let's see what processes are labeled with SSH D underscore T,
we can make use of the PS command and pass it the dash E parameter to show all processes
and the dash Z parameter to show their Se Linux context.
Basically how they're labeled by Se Linux
to remember these parameters for PS.
Just think of the word easy since the letters E and Z are pronounced easy.
Let's also pass the output to grep to filter
out only things labeled with SSH D underscore T
we can see that the SSH D process is labeled with this SSH D underscore Tse Linux type.
Now, if we take a look at how the file for the SSH daemon is labeled, we'll notice this.
The file is labeled with the SSH D underscore exec underscore T type.
And when Se Linux runs something labeled with the SSH D underscore exec underscore
T type, the process will be transitioned into a domain labeled SSH underscore T
A domain is a sort of security bubble that confines this process
and it allows it to do only what is defined
under the SSH D underscore T type enforcement rules.
Basically because the file is labeled a certain way.
Se Linux knows what restrictions it should apply to the process that starts up
currently, processes restricted in the SSH D underscore T domain can't do enough.
But if we set Se Linux to enforcing mode, we wouldn't even be able to log in.
But since it observed some actions, when we logged in earlier,
we can use another command to tell Selinux to
enable everything it witnessed up to this point.
And my module is simply a name we choose for this security package file.
We could call it anything we like.
Just use a good name to remember the purpose of this module in the future
in the output, we even get a suggestion on how to load these rules into Se Linux.
So let's run this command.
The
I
option here is used to tell the semodule
command to install this module package into Selinux.
We may notice this message depending on the Se Linux version used.
This seems to be a bug in the current version.
The default policy comes with a predefined Se Linux user named SDDM,
but we can ignore this message since we're not using SD dbm,
which is simple desktop display manager.
Anyway.
Now remember that in the current scenario,
Se Linux is still running in permissive mode
to make it actually enforce the security policies. We can run this command
and then we can check if it's actually enforcing the rules with Getenforce.
And it shows enforcing mode looks like it's doing its job
in a real scenario.
At this point,
we would test everything on our server to see if things still work as expected
since Se Linux denies everything by default.
If the current security policy doesn't have all the necessary allow rules,
some programs will be prevented from doing their job.
That's why it's a good idea to put Se Linux into enforcing
mode only when we're sure the policies include everything that's required.
It's useful to know that using the get Andfor
command puts Se Linux into enforcing mode only temporarily.
Once we reboot, it will go back into permissive mode
for the first test run. It's a good idea to enable it temporarily this way,
that way if anything goes wrong,
we can reboot our server and start over from permissive mode.
When we're certain our policies are complete,
we can permanently put Se Linux into enforcing mode
to do that. We'll edit this file
and we just change this line from permissive to enforcing.
Now, when we reboot, se Linux will start in enforcing mode
note that if the Se Linux security policies are not inclusive enough,
we might not be able to log back in or use the system normally.
So we should only enable this when we're sure that everything is set up correctly.
Now, let's get back to the module we generated with the audit to allow command.
We can see that two files were actually created.
We can explore the mymodule dot PP file since it's in
a binary format that makes it easy to plug into Se Linux
PP is short for policy package.
However, a second file is generated where we can see the rules in a text format.
The dot te extension is short for type enforcement.
If we explore the
mymodule dot te file,
we can get an idea about the Se Linux security policy generated by audit two.
Allow.
Now in a real scenario,
we'd have to scan this file thoroughly and explore everything this would
allow in the system before actually deploying these rules to Se Linux.
It is a tedious process and customization might be
necessary along with having Se Linux documentation at hand.
It's also a good idea to create a separate policy
package file for each object we want to secure.
Since this file we got from audit to allow groups rather random things together.
Let's look at our
SSHD underscore T section here.
At a first glance, this content can seem pretty intimidating,
but let's try to simplify and understand at least one of these lines.
For example, this one
we mentioned that Se Linux confines
processes into security bubbles called domains
and a domain is labeled with a certain type,
the type applied to the process decides what rules to enforce.
And that's why it's called type enforcement. In
this case, SSH D underscore T is the name of this type.
So in this policy,
we tell Se Linux that processes in the SSH D underscore
T domain type should be allowed to do certain things.
So on this line,
we simply tell it that processes under this domain should be able to take
certain actions on files labeled with the bar underscore log underscore T type.
In
this case, they should be allowed to create open and edit such files.
Now, let's exit and see why we have this line.
If we take another look at the Selinux labels or context for our
SSH daemon process,
we'll see that it's confined in the SSH D underscore T domain type
and the SSH daemon has to log its activity in the slash bar slash log slash
A
dot log file.
If we look at Se Linux labels for that file,
we'll notice that the bar underscore log underscore T type label is applied to it.
Now, let's connect the dots.
Remember the Se Linux rule we explored earlier.
Let's refresh our minds.
So in the policy generated by audit to allow with this line,
it told Se Linux to allow processes under the SSH D underscore T domain
to create and write files labeled with the bar underscore log underscore T type.
We know that in Linux,
we can set permissions on files and control what users can read,
write or execute them.
Well, with Se Linux, we get even more fine grain control.
We can limit what files a specific process should be able to access
this way. Even if someone takes control of say an engine X web server process,
they won't be able to read and modify system files.
They will be able to only touch files that
have specific labels targeted for an HTTP daemon.
Now let's clear our screen and make this easier to read.
And let's look at the label of this file. Again,
the user label is system underscore you.
The role label is object underscore R
and the type label is bar underscore log underscore
T
note how the last letter denotes. If it's a user role or type,
these three parts can find every file and every
process into what Se Linux calls a security context.
That's why the command used to change. This context is called ch con.
It's simply an abbreviation for change context.
Now to change the user label, we pass the
U option and the label we want to use. For example, unconfined U,
we type in pseudo
chcon
U,
unconfined underscore U
and then the file
to change the role, we pass the R option
and to change the type,
we pass the dash T option.
Usually we'll only need to work with the type.
Se.
Linux can also enforce certain limitations based
on the user trying to perform an action
and checking if that user can transition to certain roles.
But this is not enforced by default.
Since when we log in,
we're associated with an Se Linux user called
unconfined underscore U which can access almost everything
the user role and type that we set with CH con needs to be valid Se Linux labels.
So we can use only the things that are predefined in our security policies.
But what's a valid label?
Well, we could find out if we go through a huge part of the documentation
but a shortcut is to use commands like this.
The se info,
you
will show the valid Se Linux user labels.
R will show roles
and dash T will show types.
But to understand what actions are allowed by each type,
we have to go through a large part of the documentation.
It's just easier to look at files with similar purposes and
figure out what type we might need for a certain scenario.
In fact, we can explore this option
because at this point, the label for our all thought log file is messed up
since we changed it with the CHK
command and used random values that don't make sense for a log file
with these incorrect labels.
The SSH daemon won't be able to write to the file anymore.
So how do we fix this? Well, we have two ways.
First, we can look at the labels of other files in the varlog directory.
If we're lucky, we'll see other off
dot log files such as
a
thought
log 0.1
which have correct labels
or we can notice a similar files like CIS log. And we can guess that
a thought log would need to be labeled just like
the CIS log files since they have a similar purpose.
But manually setting each label part for the user role and type would be tedious.
So we can set all three in one shot.
We can tell the
chcon command to use another file as a reference and copy all
the label parts from the good files to the bad file.
And for this, we'll use a dack
log. We can tell
CHCON command to use another file as a reference and copy all
of the label parts from the good file to the bad file.
So I'm going to say that the DMES
file is the good file that should be used as a reference.
So here we're using that as a reference and applying it to the A dot log file.
If we take another look at the labels, we can see this is now fixed.
But how about new files and directories?
Let's say we create a website and store its files in the
default path for this purpose in the slash bar slash www directory.
So let's create the directory
and then let's create 10 new files in here
with Se Linux enabled the Apache or engine X web
server won't be able to work with these files,
if they don't have the correct labels.
So what labels do they have now?
Now this doesn't look right.
Usually, Se Linux type labels are quite suggestive
indicating a specific purpose in the name they use
bar underscore T looks pretty generic.
So in this case, it will be hard to guess what the label should be here,
but there's a command that can help us out.
Se Linux has a sort of database that it
tells it how to label files in certain directories.
In case the labels are incorrect,
we can fix it with the restorecon command short for restore context.
We'll use the
R parameter to take this action recursively on the entire
directory and any subdirectories or files that may contain.
Se Linux has a sort of database that tells
it how to label files in certain directories.
In case the labels are incorrect,
we can fix it with the restorecon command short for restore context.
We'll use the dash R parameter to take this action recursively
on the entire directory and any subdirectories or files that may contain
and let's check if this worked.
Uh huh Well, HTTP D underscore sis underscore content underscore T
seems like a much more suggestive and targeted label this time
referencing that this is for system content for the HTTP daemon.
But something that might not be immediately obvious is that restorecon by default,
only restores the correct label for the type.
For example,
let's say we change the user label for one
of these files and set it to staff underscore U
if we run restorecon again, recursively,
we'll see that the user label wasn't restored
file,
one still references the wrong user because restorecon
does not touch user and role labels.
Just the last part, the type
to force restorecon to restore all labels for the user role and type, we can pass the
F force option.
Now, if we check our files again,
we'll see that the parts of our labels have been
changed to Se Linux system defaults for this directory.
Now, here's a note
changing labels with CH Con has a possible drawback
if the file system is ever relabeled again.
Like it was when we installed Se Linux,
the custom label we set on a file can be lost.
So to futureproof our change, we can do it in a different way.
Let's say we want file 10 to always have a different type label
instead of Ch Con. We can run this command
and there's that message again, but that's ok.
So we use the Se Linux manage command and inform it about a new default file context.
We dash dash,
add an entry into its database mentioning that the dash dash
type label should be var underscore log underscore T for the
VWWW 10 file.
This just tells it about the default label but it doesn't actually change it.
So we have to follow up with this
to restore the default label
and we can confirm the change
here
for setting default labels on entire directories and the contents within
the syntax is a bit trickier,
but we can get a bit of help by listing Se Linux's entire
database of default file context slash labels for various files and directories.
And we can see this line
which basically shows us how to use
the regular expression with the parentheses to set
a default label for a directory and
all the subdirectories and files that may contain
and the command we'll use is this
note that we have to wrap the directory location between
quotes to prevent bash from interpreting the special symbols.
The
asterisk is just a regular expression that matches any kind of
file or subdirectory path we may have under that directory,
we would then have to run restorecon to restore
the default context we created for the location.
But since the directory doesn't exist, let's first create it.
And now lets restore context
and will see that the proper context has been set.
Se Linux
uses these labels to make decisions about what
it should allow to happen on the system
for the most part at least.
But we do have some exceptions
or rather shortcuts we can use,
for example, instead of defining complex type enforcement policies,
we can use what are called booleans.
It's like flipping a switch to tell Se Linux to allow or disallow a set of actions.
Here's an example,
we can take a look at supported se Linux booleans with this command.
So on a line like this,
we can see that the Vert underscore
use underscore NFS boolean is currently disabled.
The first off between parentheses
shows us that this is currently set to false or zero.
The second off signals,
the default state of this boolean that's normally set to off.
And we can see in the description what each boolean does
to enable the Vert underscore use underscore NFS boolean. We can run this command
to check the value of a certain boolean. We can run this command.
Another thing that Se Linux enforces is what ports, certain daemons can bind to,
to listen to for incoming connections
to list port bindings that are allowed for each type. We can run this command
pseudo se manage port dash dash list.
Now lets filter this to show port bindings only for
SSH.
So only port 22 is allowed
if we want to allow an additional port like 22222,
we can run something like this
and to disallow this port or delete it from our rule set.
We just changed the dash dash ad
to delete.
This covers the surface level concepts about enforcing se Linux rules.
I'd say it takes around 10 to 20 hours of study and practice
to really understand Se Linux on a deeper level.
It's a complex tool that can seem pretty overwhelming at first,
but it's certainly worth learning more about in your spare time.
Many attacks where millions of users accounts were compromised could
have been prevented by a carefully designed Se Linux policy.
So if you're passionate about cybersecurity,
it's something you'll want to look into.
Good luck on your learning path and I'll see you in the next lesson.