5

Securing Systems with Users, Groups, and Permissions

Security is a key part of managing a system and understanding the security concepts in order to provide the right access to the right resource to the right user, or group of users, is required for any system administrator.

In this chapter, we will review the basics of security in Red Hat Enterprise Linux (RHEL). We will add new users to a system and change their attributes. We will also add a user to a group and reviewing groups before making changes will be seen in this chapter. We will review how to handle user passwords and change the age requirements for them, locking or restricting user access. We will use sudo as a way to assign admin privileges to different users in the system (and even disable the root account). We will also take a deeper look into file permissions and how to change them, using an extended capability to enable commands to be run by a different user or group or to simplify group collaboration in directories.

We will cover the following topics:

  • Creating, modifying, and deleting local user accounts and groups
  • Managing groups and reviewing assignments
  • Adjusting password policies
  • Configuring sudo access for administrative tasks
  • Checking, reviewing, and modifying file permissions
  • Using special permissions

Let’s get started in the world of permissions and security with user accounts and groups.

Creating, modifying, and deleting local user accounts 
and groups

One of the first tasks that a system administrator has to do when preparing a system to be accessed by users is to create new user accounts for the people accessing the system. In this section, we will review how local accounts are created and deleted, as well as how they are assigned to groups.

The first step is to create a new user account in the system. That is done by using the useradd command. Let’s add user01 to the system by running the following:

[root@rhel-instance ~]# useradd user01

[root@rhel-instance ~]# grep user01 /etc/passwd

user01:x:1001:1001::/home/user01:/bin/bash

[root@rhel-instance ~]# id user01

uid=1001(user01) gid=1001(user01) groups=1001(user01)

With that, the user is created.

Important Note

To be able to add users, we need administrative privileges. In the current configuration, we do that by running the commands as root.

The account is created using the default options configured in the system, such as the following:

  • No password assigned: The new user will not be able to log in using a password. However, we can switch to that account by using su as root. We will see how to add a password to the user next.
  • User ID (UID): The first number over 999 available. In the command we ran before, for user01, the UID is 1001.
  • Group ID (GID): The same number as the UID. In this case, the GID is 1001.
  • Description: No description is added when creating the user. This field is left empty.
  • Home: A home directory is created in /home/$USER – in this case,/home/user01. This will be the default and main directory for the user and is where their personal preferences and files will be stored. Initial contents are copied from /etc/skel.
  • Shell: The default shell is bash.

Tip

The default options applied when a new user is created are defined in the /etc/default/useradd file.

Once the user is created, we can add (or change) the password by running, as root, the command passwd followed by the username to change it:

[root@rhel-instance ~]# passwd user01

Changing password for user user01.

New password: redhat

BAD PASSWORD: The password is shorter than 8 characters

Retype new password: redhat

passwd: all authentication tokens updated successfully

Now, the user has the new password assigned. Note two things:

  • The root user can change the password to any user without knowing the previous one (a full password reset). This is useful when a user comes back from their holidays and doesn’t remember their password.
  • In the example, we show the password assigned, redhat, but that is not shown on the screen. The password is too simple and does not meet the default complexity criteria – however, as root we can still assign it.

Let’s check the new user with the id command we learned before:

[root@rhel-instance ~]# id user01

uid=1001(user01) gid=1001(user01) groups=1001(user01)

After the steps taken in this section, we now have the user in the system and ready to be used. The main options we could have used to customize the user creation with useradd are the following:

  • -u or --uid: Assign a specific UID to the user.
  • -g or --gid: Assign a main group to the user. It can be specified by number (GID) or by name. The group needs to be created first.
  • -G or --groups: Make the user part of other groups by providing a comma-separated list of them.
  • -c or --comment: Provide a description for the user, specified between quotes if you want to use spaces.
  • -d or --home-dir: Define the home directory for the user.
  • -s or --shell: Assign a custom shell to the user.
  • -p or --password: A way to provide a password to the user. The password should be already encrypted to use this method. It is not recommended to use this option, as there are ways to capture the encrypted password. Please use passwd instead.
  • -r or --system: To create a system account instead of a user account.

What if we need to change any of the user’s properties, such as, for example, the description? The tool for that is usermod. Let’s modify the description to user01:

[root@rhel-instance ~]# usermod -c "User 01" user01

[root@rhel-instance ~]# grep user01 /etc/passwd

user01:x:1001:1001:User 01:/home/user01:/bin/bash

The usermod command uses the same options as useradd. It will be easy to customize your current users now.

Let’s create user02 as an example of how to use the options:

[root@rhel-instance ~]# useradd --uid 1002 --groups wheel

--comment "User 02" --home-dir /home/user02

--shell /bin/bash user02

[root@rhel-instance ~]# grep user02 /etc/passwd

user02:x:1002:1002:User 02:/home/user02:/bin/bash

[root@rhel-instance ~]# id user02

uid=1002(user02) gid=1002(user02) groups=1002(user02),10(wheel)

Tip

When the command line is too long, the character can be added, then press Enter and continue the command on a new line.

Now, we know how to create a user, but we may need to create a group too and add our users to it. Let’s create the finance group with the groupadd command:

[root@rhel-instance ~]# groupadd finance

[root@rhel-instance ~]# grep finance /etc/group

finance:x:1003:

We can add the user01 and user02 users to the finance group:

[root@rhel-instance ~]# usermod -aG finance user01

[root@rhel-instance ~]# usermod -aG finance user02

[root@rhel-instance ~]# grep finance /etc/group

finance:x:1003:user01,user02

Important Note

We are using the -aG option to add the user to the group, instead of modifying the groups the user belongs to.

Once we know how to create users and groups, let’s check how to delete them with the userdel command:

[root@rhel-instance ~]# userdel user01

[root@rhel-instance ~]# grep user01 /etc/passwd

[root@rhel-instance ~]# id user01

id: 'user01': no such user

[root@rhel-instance ~]# grep user02 /etc/passwd

user02:x:1002:1002:User 02:/home/user02:/bin/bash

[root@rhel-instance ~]# id user02

uid=1002(user02) gid=1002(user02) groups=1002(user02),10(wheel),1003(finance)

[root@rhel-instance ~]# ls /home/

user  user01  user02

[root@rhel-instance ~]# rm -rf /home/user01/

As you can see, we needed to manually delete the home directory. This way of removing a user is good if we want to keep its data for future use.

To fully remove a user, we shall apply the -r option. Let’s try it with user02:

[root@rhel-instance ~]# userdel -r user02

[root@rhel-instance ~]# ls /home/

user  

[root@rhel-instance ~]# grep user02 /etc/passwd

[root@rhel-instance ~]# id user02

id: 'user02': no such user

Now, let’s remove the finance group with the groupdel command:

[root@rhel-instance ~]# groupdel finance

[root@rhel-instance ~]# grep finance /etc/group

As we have seen, it’s simple and easy to create users and groups in RHEL and make simple assignments. In the next section, let’s check in more depth how to manage groups and assignments to them.

Managing groups and reviewing assignments

We have seen how to create a group with groupadd and delete it with groupdel. Let’s see how to modify a created group with groupmod.

Let’s create a group to work with. We will create the misspelled acounting group by running the following:

[root@rhel-instance ~]# groupadd -g 1099 acounting

[root@rhel-instance ~]# tail -n1 /etc/group

acounting:x:1099:

You see we made a mistake in the name by not spelling it accounting. We may even have added some user accounts to it and we need to modify it. We can do so using groupmod and running the following:

[root@rhel-instance ~]# groupmod -n accounting acounting

[root@rhel-instance ~]# tail -n1 /etc/group

accounting:x:1099:

Now, we’ve seen how we modify the group name. We can modify not just the name but the GID by using the -g option:

[root@rhel-instance ~]# groupmod -g 1111 accounting

[root@rhel-instance ~]# tail -n1 /etc/group

accounting:x:1111:

We can see which groups are assigned to a user by running the groups command:

[root@rhel-instance ~]# groups user

user : user wheel

With this, we are ready to manage groups and users in a Linux system. Let’s move on to password policies.

Adjusting password policies

As was mentioned in Chapter 3, Basic Commands and Simple Shell Scripts, users are stored in the /etc/passwd file while the encrypted passwords, or password hashes, are stored in the /etc/shadow file.

Tip

A hashing algorithm is made so that it generates a precise string of characters, or a hash, from a provided piece of data (that is, a file or a word). It does it in a way that it will always generate the same hash from the same original data, but the original data is almost impossible to recreate from the hash. That’s why they are used to store passwords or verify the integrity of a downloaded file.

Let’s take a look at one example by running the grep user as root against /etc/shadow:

user:$6$tOT/cvZ4PWRcl8XX$0v3.ADE/ibzlUGbDLer0ZYaMPNRJ5gK17LeKno MfKK9 .nFz8grN3IafmHvoHPuh3XrU81nJu0.is5znztB64Y/:18650:0:99999 :7:3:19113:

As with the password file, the data stored in /etc/shadow has an entry per line and the fields are separated by colons (:):

  • user: The account name. It should be the same one as in /etc/passwd.
  • $6$tOT/cvZ4PWRcl8XX$0v3.ADE/ibzlUGbDLer0ZYaMPNRJ5gK17LeKnoMfKK 9.nFz8grN3IafmHvoHPuh3XrU81nJu0.is5znztB64Y/: The password hash. It contains three parts separated by $:
    • $6: The algorithm used to encrypt the file. In this case, the value 6 indicates that it is SHA-512. The number 1 is for the old, now insecure, MD5 algorithm.
    • $tOT/cvZ4PWRcl8XX: The salt password. This token is used to improve password encryption.
    • $0v3.ADE/ibzlUGbDLer0ZYaMPNRJ5gK17LeKnoMfKK9.nFz8grN3IafmHvoHPuh3XrU81nJu0.is5znztB64Y/: An encrypted password hash. Using salt and the SHA-512 algorithm, this token is created. When the user validates, the process is run again and if the same hash is generated, the password is validated and access is granted.
  • 18650: The time and date when the password was last changed. The format is the number of days since 1970-01-01 00:00 UTC (this date is also known as the epoch).
  • 0: The minimum number of days until the user can change the password again.
  • 99999: The maximum number of days until the user has to change the password again. If empty, it won’t expire.
  • 7: The number of days the user will be warned that the password is about to expire.
  • 3: The number of days the user can still log in even when the password has expired.
  • 19113: The date on which the password should expire. If empty, it won’t expire on a specific date.
  • <empty>: The last colon is left to allow us to add new fields easily.

Tip

To convert the date field to a human-readable date, you can run the following command: date -d '1970-01-01 UTC + 18650 days'.

How do we change the expiration dates for passwords? The tool to do so is chage, for change age. Let’s first review the options that can be used in the same order as they are stored in /etc/shadow:

  • -d or --lastday: The time and date when the password was last changed. The format for it is YYYY-MM-DD.
  • -m or --mindays: The minimum number of days until the user can change the password again.
  • -W or --warndays: The number of days the user will be warned that the password is about to expire.
  • -I or --inactive: The number of days, once the password has expired, that will have to pass before the account is locked.
  • -E or --expiredate: The date after which the user’s account will be locked. The date should be expressed in the YYYY-MM-DD format.

Let’s try it. First, we create the usertest account:

[root@rhel-instance ~]# adduser usertest

[root@rhel-instance ~]# grep usertest /etc/shadow

usertest:!!:19062:0:99999:7:::

Important Note

adduser and useradd have similar functionality in RHEL 9. Feel free to type it the way you feel most comfortable.

You’ll notice in the previous example from the two exclamation marks (!!) in bold that the password is not set and we are using the defaults. Let’s change the password and check the difference. Use any password you like:

[root@rhel-instance ~]# passwd usertest

Changing password for user usertest.

New password:

Retype new password:

passwd: all authentication tokens updated successfully.

[root@rhel-instance ~]# grep usertest /etc/shadow

usertest:$6$4PEVPj7M4GD8CH.4$VqiYY.IXetwZA/g54bFP1ZJwQ/yc6bnaFauHGA1 1eFzsGh/uFbJwxZCQTFHIASuamBz.27gb4ZpywwOA840eI.:19062:0:99999:7:::

The password hash is created and the date for the last change is just kept the same as the current date. Let’s establish some options:

[root@rhel-instance ~]# chage --mindays 0 --warndays 7 --inactive 3 --expiredate 2030-01-01 usertest

[root@rhel-instance ~]# grep usertest /etc/shadow

usertest:$6$4PEVPj7M4GD8CH.4$VqiYY.IXetwZA/g54bFP1ZJwQ/yc6bnaFauHGA1 1eFzsGh/uFbJwxZCQTFHIASuamBz.27gb4ZpywwOA 840eI.:19062:0:99999:7:3:21915:

[root@rhel-instance ~]# date -d '1970-01-01 UTC + 21915 days'

Tue Jan  1 01:00:00 AM CET 2030

Please notice the changes in the /etc/shadow file corresponding to the values specified for chage. We can check the changes with the –l option for chage:

[root@rhel-instance ~]# chage -l usertest

Last password change                  : mar 11, 2022

Password expires                      : never

Password inactive                     : never

Account expires                       : Jan 01, 2030

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

Important Note

In RHEL 9 some of the password controls are also configured using the /etc/security/pwquality.conf file, for example, the minimal acceptable size for the new password (minlen parameter) or the maximum credit for having uppercase or lowercase characters. You may want to check this file in case you need to change these parameters.

To change the default values, we will edit /etc/login.defs. Let’s check the section for the most common changes:

# 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    99999

PASS_MIN_DAYS    0

PASS_WARN_AGE    7

Please take some minutes to review the options in /etc/login.defs.

Now, we could have a situation in which a user has left the company. How can we lock the account so the user cannot access the system? The usermod command has the –L option, for lock, to do so. Let’s try it. First, let’s log into the system:

Figure 5.1 – The usertest user account logging into the system

Figure 5.1 – The usertest user account logging into the system

Now, let’s lock the account:

[root@rhel-instance ~]# usermod -L usertest

[root@rhel-instance ~]# grep usertest /etc/shadow

usertest:!$6$4PEVPj7M4GD8CH.4$VqiYY.IXetwZA/g54bFP1ZJwQ/yc6bnaFauHGA 11eFzsGh/uFbJwxZCQTFHIASuamBz.27gb4ZpywwOA840eI.:18651:0:99999:7:3 :21915:

Notice that there is a ! character added before the password hash. This is the mechanism used to lock it. Let’s try to log in again:

Figure 5.2 – The usertest user account not being able to log into the system

Figure 5.2 – The usertest user account not being able to log into the system

The account can be unlocked by using the –U option:

[root@rhel-instance ~]# usermod -U usertest

[root@rhel-instance ~]# grep usertest /etc/shadow

usertest:$6$4PEVPj7M4GD8CH.4$VqiYY.IXetwZA/g54bFP1ZJwQ/yc6bnaFauHGA1 1eFzsGh/uFbJwxZCQTFHIASuamBz.27gb4ZpywwOA840eI.:19062:0:99999:7:3:21 915:

Now, you can see that the ! character is removed. Feel free to try logging in again.

Important Note

To fully lock the account from access, not just from logging in with a password (there are other mechanisms), we should set the expiry date to 1.

Another common use case is when you want users to access the system, such as having a network shared directory (that is, via NFS or CIFS, as explained in Chapter 12, Managing Local Storage and Filesystems), but you do not want them to be able to run commands in the system. For that, we can use a very special shell – the nologin shell. Let’s assign that shell to the usertest user account using usermod:

[root@rhel-instance ~]# usermod -s /sbin/nologin usertest

[root@rhel-instance ~]# grep usertest /etc/passwd

usertest:x:1001:1001::/home/usertest:/sbin/nologin

[root@rhel-instance ~]# su - usertest

This account is currently not available.

[root@rhel-instance ~]# usermod -s /bin/bash usertest

[root@rhel-instance ~]# su - usertest

[usertest@rhel-instance ~]$

Note that we are reviewing the changes in /etc/passwd this time, as it is where the modification is applied.

As you can see, it’s easy to set the values for password aging for any user, lock them, or restrict access to the system. Let’s move on to more administrative tasks and how to delegate admin access.

Configuring sudo access for administrative tasks

There is a way to delegate administrative access to users in RHEL, and it is done with a tool called sudo, which stands for Super User Do.

It not only allows you to grant full administrative privileges to users or groups but also to be very granular about the privileged commands that some users may be able to execute.

Let’s start by understanding the default configuration and how to change it.

Understanding sudo configuration

The tool has its main configuration file in /etc/sudoers and includes this part in the default configuration:

root ALL=(ALL)  ALL
%wheel    ALL=(ALL)  ALL
## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)
#includedir /etc/sudoers.d

Let’s analyze these four specific lines one by one to understand what they do:

  1. The first line enables the root user to use sudo for any command that they want to run:

    root ALL=(ALL)  ALL

  2. The second line enables the user in the wheel group to use sudo for any command that they want to run. We will explain the details of the syntax later:

    %wheel    ALL=(ALL)  ALL

Important Note

Please do not disable the wheel group directive unless there is an important reason to do so. This behavior is expected by other programs to be available and disabling it may cause some problems.

  1. The third line, and all the lines starting with #, are considered comments, and they are only intended to add descriptive content with no effect on the final configuration. It is possible to include other sudoers files from within the sudoers file currently being parsed using the @include and @includedir directives:

    ## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)

  2. The fourth line is the only exception to the previous rule. This line enables the /etc/sudoers.d directory as a source for configuration files. We can drop a file in that folder and it will be used by sudo. For compatibility with sudo versions prior to 1.9.1, #include and #includedir are also accepted:

    #includedir /etc/sudoers.d

The exception to this last rule is files that end with ~ or contain a . (dot) character.

As you have seen, the default configuration enables root and the members of the wheel group to run any command as an administrator using sudo.

The easiest way to use it is to add a user to the wheel group to grant that user full admin privileges. An example of how to modify the usertest account to make it an admin account is as follows:

[root@rhel-instance ~]# usermod -aG wheel usertest

[root@rhel-instance ~]# groups usertest

usertest : usertest wheel

Important Note

For cloud instances, the account root does not have a valid password assigned. To be able to manage the mentioned cloud instance, in some clouds such as Amazon Web Services (AWS), a user is created by default and added to the wheel group. In the case of AWS, the default user account is ec2-user. In other clouds, a custom user is also created and also added to the wheel group.

To edit the /etc/sudoers file, as happens with other sensitive files, there is a tool that helps not only ensure that two admins are not editing it simultaneously but also that the syntax is correct. In this case, the tool to edit it is visudo.

Using sudo to run admin commands

We will use the user account in these examples. As you may remember, in Chapter 1, Getting RHEL Up and Running, we enabled the checkbox in which we requested the account to be the administrator. Under the hood, the account was added to the wheel group, so we can start using sudo to run admin commands.

Let’s log in with the user account and try to run an administrative command such as adduser:

[root@rhel-instance ~]# su - user

[user@rhel-instance ~]$ adduser john

adduser: Permission denied.

adduser: cannot lock /etc/passwd; try again later.

As you can see, we receive a Permission denied error message. To be able to run it with sudo, we only need to add it to the beginning of the command line:

[user@rhel-instance ~]$ sudo adduser john

We trust you have received the usual lecture from the local System

Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.

    #2) Think before you type.

    #3) With great power comes great responsibility.

[sudo] password for user:

[user@rhel-instance ~]$ id john

uid=1002(john) gid=1002(john) groups=1002(john)

In this case, we see that we have been shown a warning message that is shown the first time we run sudo successfully. Then, we are asked for our own password – not the admin password, as there may not even be one, but the one we have for the user running sudo. Once the password is typed correctly, the command is run and registered in the system journal:

mar 11 19:44:26 rhel-instance.example.com useradd[1710]: user : TTY=pts/0 ; PWD=/home/user ; USER=root ; COMMAND=/sbin/adduser john

Important Note

Once you have run sudo successfully, it will remember that validation for 15 minutes (as the default behavior). This is done so you don’t have to type your password again and again if you need to run more than one administrative command in a session. To increase it to 30 minutes, we can add the following line using visudo:

Defaults:USER timestamp_timeout=30.

Sometimes, you want to have an interactive session so that there is no need to type sudo again and again. For that, the –i option is really useful. Let’s try it:

[user@rhel-instance ~]$ sudo -i

[sudo] password for user:

[root@rhel-instance ~]#

Let’s now move on to customizing the configuration of sudo in the sudoers file.

Configuring sudoers

We have seen the details of the default /etc/sudoers file in the previous section. Let’s see a couple of examples of how to make a more granular configuration.

Let’s start by making sudo run admin commands without requesting a password for the users in the wheel group. We can run visudo and make the line that starts with %wheel look as follows:

%wheel        ALL=(ALL)       NOPASSWD: ALL

Save it. Note that there is a commented line in the configuration file with that configuration. Now, let’s try it:

[user@rhel-instance ~]$ sudo adduser ellen

[user@rhel-instance ~]$ id ellen

uid=1003(ellen) gid=1003(ellen) groups=1003(ellen)

We can now create a file with your favorite editor to make the new user account, ellen, able to run admin commands. Let’s create the /etc/sudoers.d/ellen file with this content:

ellen ALL=(ALL)  ALL

With this, we are using the /etc/sudoers.d directory to extend the sudo configuration.

We will review the detailed configuration of sudoers here despite it not being part of the RHCSA exam. As you can see, there are three fields separated by spaces or tabs to define policies in the configuration files. Let’s review them:

  • The first field is to specify who is affected by the policy:
    • We can add users by simply putting the username in the first field.
    • We can add groups by using the % character before the name of the group in the first field.
  • The second field is for where the policy applies:
    • We have so far used ALL=(ALL) to specify everything.
    • In the first part of this field, we can define a group of computers to be run, such as SERVERS=10.0.0.0/255.255.255.0.
    • In the second part, we can specify commands such as NETWORK=/usr/sbin/ip.
    • Between parentheses is the user account that can be used to run the command.
  • The third field is to specify which commands will use the password and which won’t.

The syntax goes as follows:

user  hosts = (run-as) commands

Let’s see an example:

Runas_AliasDB = oracle

Host_Alias SERVERS=10.0.0.0/255.255.255.0

Cmnd_Alias NETWORK=/usr/sbin/ip

pete  SERVERS=NETWORK

julia SERVERS=(DB)ALL

We have already seen how to provide administrative access to users in RHEL and even how to do it in a very granular manner. Let’s move on now to the section on working with file permissions.

Checking, reviewing, and modifying file permissions

So far, we have learned how to create users and groups and even provide administrative capabilities to them. It’s now time to see how permissions work at the file and directory level.

As you’ll remember, in Chapter 3, Basic Commands and Simple Shell Scripts, we already saw how to see the permissions that are applied to a file. Let’s review them now and dive deeper.

Let’s get the permissions info for some example files by listing it with –l, for the long option. Remember to run this as the root user (or using sudo):

[root@rhel-instance ~]# ls -l /usr/bin/bash

-rwxr-xr-x. 1 root root 1390064 Aug 9  2021 /usr/bin/bash

[root@rhel-instance ~]# ls -l /etc/passwd

-rw-r--r--. 1 root root 1740 Mar 11 21:35 /etc/passwd

[root@rhel-instance ~]# ls -l /etc/shadow

----------. 1 root root 1170 Mar 11 21:35 /etc/shadow

[root@rhel-instance ~]# ls -ld /tmp

drwxrwxrwt. 5 root root 4096 Mar 11 17:35 /tmp

Remember that, in Linux, everything is a file.

Now, let’s review the five different blocks of information that the permissions include by using the ones for /usr/bin/bash:

-rwxr-xr-x.

The blocks are as follows:

Table 5.1 – File permissions by block

Table 5.1 – File permissions by block

Let’s review them again, as they are very important:

  • Block 1 is for the special permissions that the file may have. If it is a regular file and has no special permissions (as in this case), it will appear as -:
    • Directories will appear with d.
    • Links, usually symbolic links, will appear with an l.
    • Special permissions to run a file as a different user or group, called setuid or setgid, will appear as s.
    • Special permissions for directories so that the owner can only remove or rename the file, called a sticky bit, will appear as t.
  • Block 2 is the permissions for the user owning the file, and consists of three characters:
    • The first one, r, is the read permission assigned.
    • The second one, w, is the write permission assigned.
    • The third one, x, is the executable permission (note that the executable permission for directories means being able to enter them.)
  • Block 3 is permissions for the group. It consists of the same three characters for read, write, and execute (rwx). In this case, write is missing.
  • Block 4 is the permissions for others. It also consists of the same three characters for read, write, and execute (rwx) as before. As in the previous block, write is missing.
  • Block 5 indicates that there is an SELinux context applied to the file. More on this topic in Chapter 10, Keeping Your System Hardened with SELinux.

To change permissions for a file, we will use the chmod command.

First, let’s create a file:

[root@rhel-instance ~]# touch file.txt

[root@rhel-instance ~]# ls -l file.txt

-rw-r--r--. 1 root root 0 Mar 11 22:30 file.txt

As you can see, the file is created with your username as the owner, your main group as the group, and a default set of permissions. The default set of permissions is defined by umask, and in RHEL, the defaults for newly created file permissions are as follows:

  • User: Read and write
  • Group: Read
  • Others: Read

To change permissions using chmod, we specify the changes with three characters:

  • The first one, which determines whom the change affects:
    • u: User
    • g: Group
    • o: Others
  • The second one to add or remove permissions:
    • +: Add
    • -: Remove
  • The third one, which determines the permission to be changed:
    • r: Read
    • w: Write
    • x: Execute

So, to add write permissions to the group, we can run the following:

[root@rhel-instance ~]# chmod g+w file.txt

[root@rhel-instance ~]# ls -l file.txt

-rw-rw-r--. 1 root root 0 Mar 11 22:30 file.txt

And to remove read permissions from others, we run the following:

[root@rhel-instance ~]# chmod o-r file.txt

[root@rhel-instance ~]# ls -l file.txt

-rw-rw----. 1 root root 0 Mar 11 22:30 file.txt

The permissions are stored in four octal digits. This means that special permissions are stored in a number from 0 to 7, the same way user, group, and other permissions are stored, each one of them with a number from 0 to 7.

Some examples are shown as follows:

Table 5.2 – Example file permissions

Table 5.2 – Example file permissions

How does it work? We assign a number (power of 2) for each permission:

  • Read: 2^2 = 4
  • Write: 2^1 = 2
  • Execute: 2^0 = 1
  • Nothing: 0

We add them:

rwx = 4 + 2 + 1 = 7
rw- = 4 + 2 = 6
r-x = 4 + 1 = 5
r-- = 4
--- = 0

This is how we can assign permissions using numbers. Now, let’s try it:

[root@rhel-instance ~]# chmod 0755 file.txt

[root@rhel-instance ~]# ls -l file.txt

-rwxr-xr-x. 1 root root 0 Mar 11 22:30 file.txt

[root@rhel-instance ~]# chmod 0640 file.txt

[root@rhel-instance ~]# ls -l file.txt

-rw-r-----. 1 root root 0 Mar 11 22:30 file.txt

[root@rhel-instance ~]# chmod 0600 file.txt

[root@rhel-instance ~]# ls -l file.txt

-rw-------. 1 root root 0 Mar 11 22:30 file.txt

As we said before, the default configuration of permissions is set by umask. We can very easily see the value:

[root@rhel-instance ~]# umask

0022

[root@rhel-instance ~]# umask –S

u=rwx,g=rx,o=rx

All the newly created files have execute permissions removed (1).

With this umask, 0022, the one provided by default in RHEL, we will have write permissions for group and others also removed (2).

Even when it is not recommended to change umask, we could give it a try to learn how it works. Let’s start by using the most permissive umask, 0000, to see how all read and write permissions are assigned to newly created files:

[root@rhel-instance ~]# umask 0000

[root@rhel-instance ~]# touch file2.txt

[root@rhel-instance ~]# ls -l file2.txt

-rw-rw-rw-. 1 root root 0 Mar 11 22:33 file2.txt

Now, let’s use the more restrictive umask for group and others permissions:

[root@rhel-instance ~]# umask 0066

[root@rhel-instance ~]# touch file3.txt

[root@rhel-instance ~]# ls -l file3.txt

-rw-------. 1 root root 0 Mar 11 22:33 file3.txt

If we try a higher number, it won’t work and will return an error:

[root@rhel-instance ~]# umask 0088

-bash: umask: 0088: octal number out of range

You can see that the effect of 0066 and 0077 is the same:

[root@rhel-instance ~]# umask 0077

[root@rhel-instance ~]# touch file4.txt

[root@rhel-instance ~]# ls -l file4.txt

-rw-------. 1 root root 0 Mar 11 22:35 file4.txt

Let’s re-establish umask in our session to the defaults to continue practicing:

[root@rhel-instance ~]# umask 0022

Now, we may find ourselves with the need to create a directory for a specific user or group or to change the owner of a file. To be able to change the ownership of a file or directory, the chown or chgrp tools are used. Let’s see how it works. Let’s move to /var/tmp and create the folders for finance and accounting:

[root@rhel-instance ~]# cd /var/tmp/

[root@rhel-instance tmp]# mkdir finance

[root@rhel-instance tmp]# mkdir accounting

[root@rhel-instance tmp]# ls -l

total 0

drwxr-xr-x. 2 root root 6 Mar 11 22:35 accounting

drwxr-xr-x. 2 root root 6 Mar 11 22:35 finance

Now, let’s create the groups for finance and accounting:

[root@rhel-instance tmp]# groupadd finance

[root@rhel-instance tmp]# groupadd accounting

groupadd: group 'accounting' already exists

In this example, the accounting group was already created. Let’s change the group for each directory with chgrp:

[root@rhel-instance tmp]# chgrp accounting accounting/

[root@rhel-instance tmp]# chgrp finance finance/

[root@rhel-instance tmp]# ls -l

total 0

drwxr-xr-x. 2 root accounting 6 Mar 11 22:35 accounting

drwxr-xr-x. 2 root finance    6 Mar 11 22:35 finance

Now, we create users for sonia and matilde, and assign them to finance and accounting respectively:

[root@rhel-instance tmp]# adduser sonia

[root@rhel-instance tmp]# adduser matilde

[root@rhel-instance tmp]# usermod -aG finance sonia

[root@rhel-instance tmp]# usermod -aG accounting matilde

[root@rhel-instance tmp]# groups sonia

sonia : sonia finance

[root@rhel-instance tmp]# groups matilde

matilde : matilde accounting

Now, we can create a personal folder for each under their group folder:

[root@rhel-instance tmp]# cd finance/

[root@rhel-instance finance]# mkdir personal_sonia

[root@rhel-instance finance]# chown sonia personal_sonia

[root@rhel-instance finance]# ls -l

total 0

drwxr-xr-x. 2 sonia root 6 Mar 11 22:44 personal_sonia

[root@rhel-instance finance]# chgrp sonia personal_sonia/

[root@rhel-instance finance]# ls -l

total 0

drwxr-xr-x. 2 sonia sonia 6 Mar 11 22:44 personal_sonia

There is a way to specify a user and group to chown – using the : separator. Let’s use it with matilde:

[root@rhel-instance tmp]# cd ../accounting

[root@rhel-instance accounting]# mkdir personal_matilde

[root@rhel-instance accounting]# chown matilde:matilde

personal_matilde

[root@rhel-instance accounting]# ls -l

total 0

drwxr-xr-x. 2 matilde matilde 6 Mar 11 22:46 personal_matilde

If we want to change the permissions for a full branch, we can use chown with –R, the recursive option. Let’s copy a branch and change its permissions:

[root@rhel-instance accounting]# cp -rv /usr/share/doc/audit personal_matilde/

'/usr/share/doc/audit' -> 'personal_matilde/audit'

'/usr/share/doc/audit/ChangeLog' -> 'personal_matilde/audit/ChangeLog'

'/usr/share/doc/audit/README' -> 'personal_matilde/audit/README'

'/usr/share/doc/audit/auditd.cron' -> 'personal_matilde/audit/auditd.cron'

[root@rhel-instance accounting]# chown -R matilde:matilde

personal_matilde/audit

[root@rhel-instance accounting]# ls -l personal_matilde/audit/

total 20

-rw-r--r--. 1 matilde matilde  271 Mar 11 22:56 auditd.cron

-rw-r--r--. 1 matilde matilde 8006 Mar 11 22:56 ChangeLog

-rw-r--r--. 1 matilde matilde 4953 Mar 11 22:56 README

With this, we have a good understanding of permissions in RHEL, their default behaviors, and how to work with them.

Let’s move on to some more advanced topics about permissions.

Using special permissions

As we’ve seen in the previous section, there are special permissions that could be applied to files and directories. Let’s start by reviewing Set-UID (or SUID) and Set-GUID (or SGID).

Understanding and applying SUID

Let’s review how SUID applies to files and directories:

  • SUID permission applied to a file: When applied to an executable file, this file will run as if the owner of the file was running it, applying the permissions.
  • SUID permission applied to a directory: No effect.

Let’s check a file with SUID:

[root@rhel-instance ~]# ls -l /usr/bin/passwd

-rwsr-xr-x. 1 root root 32648 Aug 10  2021 /usr/bin/passwd

Tip

In this example, s in the executable bit of the user block is lowercase because the executable bit is set – if the executable bit isn’t set, it will be in uppercase (S).

The passwd command requires root permissions to change hashes in the /etc/shadow file.

To apply this permission, we can use the chmod command, applying u+s permissions:

[root@rhel-instance ~]# touch testsuid

[root@rhel-instance ~]# ls -l testsuid

-rw-r--r--. 1 root root 0 Mar 11 23:16 testsuid

[root@rhel-instance ~]# chmod u+s testsuid

[root@rhel-instance ~]# ls -l testsuid

-rwsr--r--. 1 root root 0 Mar 11 23:16 testsuid

Tip

Be very careful when assigning SUID to files as root. If you leave write permissions on the file, any user will be able to change the content and execute anything as root.

Understanding and applying SGID

Let’s review how SGID applies to files and directories:

  • SGID permission applied to a file: When applied to an executable file, this file will run with the group permissions of the file.
  • SGID permission applied to a directory: New files created in that directory will have the group of the directory applied to them.

Let’s check a file with SGID:

[root@rhel-instance ~]# ls -l /usr/bin/write

-rwxr-sr-x. 1 root tty 24456 Aug 20  2021 /usr/bin/write

We can try applying the permission to a file with chmod using g+s:

[root@rhel-instance ~]# touch testgid

[root@rhel-instance ~]# chmod g+s testgid

[root@rhel-instance ~]# ls -l testgid

-rw-r-sr--. 1 root root 0 Mar 11 23:23 testgid

Now, let’s try it with a directory. Let’s go to our previous example:

[root@rhel-instance ~]# cd /var/tmp/

[root@rhel-instance tmp]# ls

accounting  finance

[root@rhel-instance tmp]# chmod g+s accounting finance

[root@rhel-instance tmp]# ls -l

total 0

drwxr-sr-x. 3 root accounting 30 Mar 11 23:46 accounting

drwxr-sr-x. 3 root finance    28 Mar 11 23:44 finance

[root@rhel-instance tmp]# touch finance/testfinance

[root@rhel-instance tmp]# ls -l finance/testfinance

-rw-r--r--. 1 root finance 0 Mar 11 23:47 finance/testfinance

[root@rhel-instance tmp]# touch accounting/testaccounting

[root@rhel-instance tmp]# ls -l accounting/testaccounting

-rw-r--r--. 1 root accounting 0 Mar 11 23:47 accounting/testaccounting

You can see how, after applying SGID to the folders, they show the s permission for the group (in bold). Also, when creating new files in those directories, the group assigned to them is the same as the group that the parent directory has (also in bold). This way, we ensure group permissions are properly assigned.

Using the sticky bit

The last of the permissions to be used is the sticky bit. It only affects directories and what it does is simple: when a user creates a file in a directory with the sticky bit, only that user can edit or delete that file.

Let’s check an example:

[root@rhel-instance ~]# ls -ld /tmp

drwxrwxrwt. 8 root root 4096 Mar 11 23:31 /tmp

We could apply those to the previous example, also with chmod using o+t:

[root@rhel-instance ~]# cd /var/tmp/

[root@rhel-instance tmp]# ls -l

total 0

drwxr-sr-x. 3 root accounting 52 Mar 11 23:47 accounting

drwxr-sr-x. 3 root finance    47 Mar 11 23:47 finance

[root@rhel-instance tmp]# chmod o+t accounting finance

[root@rhel-instance tmp]# ls -l

total 0

drwxr-sr-t. 3 root accounting 52 Mar 11 23:47 accounting

drwxr-sr-t. 3 root finance    47 Mar 11 23:47 finance

Let’s give it a try. We will add the sonia user to the accounting group. We will grant a write permission to the group for the /var/tmp/accounting directory. Then, we will create a file with the matilde user and try to delete it with the sonia user. Let’s go:

[root@rhel-instance ~] # usermod -aG accounting sonia

[root@rhel-instance ~]# cd /var/tmp/

[root@rhel-instance tmp]# chmod g+w accounting

[root@rhel-instance tmp]# ls -l

total 0

drwxrwsr-t. 3 root accounting 52 Mar 11 23:47 accounting

drwxr-sr-t. 3 root finance    47 Mar 11 23:47 finance

[root@rhel-instance tmp]# su - matilde

[matilde@rhel-instance ~]$ cd /var/tmp/accounting/

[matilde@rhel-instance accounting]$ touch teststickybit

[matilde@rhel-instance accounting]$ exit

logout

[root@rhel-instance tmp]# su - sonia

[sonia@rhel-instance ~]$ cd /var/tmp/accounting/

[sonia@rhel-instance accounting]$ ls -l teststickybit

-rw-rw-r--. 1 matilde accounting 0 Mar 11 23:50 teststickybit

[sonia@rhel-instance accounting]$ rm -f teststickybit

rm: cannot remove 'teststickybit': Operation not permitted

Tip

The numeric values for special permissions are SUID = 4, SGID = 2, and sticky bit = 1.

With this, we have completed how to manage permissions in RHEL.

Summary

In this chapter, we have reviewed the permission management system in RHEL, implemented using traditional permissions. We have learned how to create user accounts and groups and how to ensure that passwords are managed correctly. We have also learned how passwords are stored in the system and even how to block shell access to a user. We have created files and folders, assigning permissions to them and ensuring that users can collaborate with an enforced set of rules.

These are the basics of managing access in RHEL and will be very useful to avoid security issues when managing systems. As this is such an important topic, we recommend reviewing this chapter carefully, reading the man pages for the commands shown, and making an effort to get a really good understanding of the topic, as it will avoid any uncomfortable situations in the future.

Now, you are ready to start providing services to users and managing their access, which is what we will cover in the next chapter. Remember to thoroughly practice and test the lessons learned here.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset