Objective
Learn how to restrict users access on a Linux machine
Operating System and Software Versions
- Operating System: – All Linux distributions
Requirements
- Root permissions
Difficulty
EASY
Conventions
- # – requires given linux commands to be executed with root privileges either
directly as a root user or by use ofsudo
command - $ – requires given linux commands to be executed as a regular non-privileged user
Introduction
In this tutorial we are going to learn how to restrict access to a Linux machine by interacting with two files: /etc/securetty
, which let us specify from what console it’s possible to login directly as root, and /etc/security/access.conf
, in which we can set some rules to restrict access for specified users or groups from certain origins.
Restrict root login
The first thing we are going to do, it’s to learn how to edit the /etc/securetty
file in order to allow direct root access only on some specific consoles. Let’s take a look at the file: this is what it looks like on a CentOS7 machine:
console vc/1 vc/2 vc/3 vc/4 vc/5 vc/6 vc/7 vc/8 vc/9 vc/10 vc/11 tty1 tty2 tty3 tty4 tty5 tty6 tty7 tty8 tty9 tty10 tty11 ttyS0 ttysclp0 sclp_line0 3270/tty1 hvc0 hvc1 hvc2 hvc3 hvc4 hvc5 hvc6 hvc7 hvsi0 hvsi1 hvsi2 xvc0
What we see there it’s just a list of all the terminals from which direct access as the root user is allowed. Let’s focus on the tty
devices for now. Open the file with a text editor and comment the tty1
entry:
[...] #tty1 tty2 tty3 tty4 tty5 tty6 tty7 tty8 tty9 tty10 tty11 [...]
Save and exit the text editor. Now, if we switch to the first tty
by pressing CTRL + alt + 1
or by running chvt 1
, and try to login as root, we will have the following result:
As expected, the system denied us access as root from the specified tty. To gain root privileges and accomplish administrative tasks, we must then login as a normal user and then use sudo
or su
(or login from another tty if allowed).
Be aware that this will not affect the ability to login as root when using ssh. To avoid that specific behaviour you should configure the ssh server, modifying the /etc/ssh/sshd_config
file, and set the PermitRootLogin
directive to no
Setup access rules in /etc/security/access.conf
If the /etc/securetty
file allows us to specify from which terminal it is possible to login directly as root, setting up access rules in the /etc/security/access.conf
file, we can allow or deny access to specific users or groups from specific origins.
Insert the pam_access.so module
Before setting up our rules, we need to modify /etc/pam.d/login
, to add the pam_access.so
module which will allow pam
to scan the access.conf
file for the rules we will define. Use your favorite text editor to modify the file so that it looks this way:
#%PAM-1.0 auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so auth substack system-auth auth include postlogin account required pam_nologin.so account required pam_access.so account include system-auth password include system-auth # pam_selinux.so close should be the first session rule session required pam_selinux.so close session required pam_loginuid.so session optional pam_console.so # pam_selinux.so open should only be followed by sessions to be executed in the user context session required pam_selinux.so open session required pam_namespace.so session optional pam_keyinit.so force revoke session include system-auth session include postlogin -session optional pam_ck_connector.so
What we have done is to add the account required pam_access.so
line at the end of the account
section. Now that we setup pam
we can start to talk about access rules.
The rules syntax
To define a rule in the access.conf
file, we must respect a very simple and clear syntax. A rule is composed of three sections, separated by a colon:
permission : users : origins
The first part of the rule specifies the permissions, and consists of a -
or +
sign: the former creates what we can call a ‘deny’ rule, while the latter specifies a rule where access permissions are granted.
In the second part we provide the subjects of the rule. The section consists of a list of groups or login names. To avoid conflicts between users and groups which can be named in the same way, the group entries can be specified in brackets, but only if the nodefgroup
option is set in the /etc/pam.d/login
file we modified above, at the end of the line we added.
The third part of the rule specifies the source from which the access is either allowed or denied, being it: one or more ttys
, host names, host addresses, or domains.
Keywords
The rule syntax let us even use some powerful keywords. First of all we have ALL
. This keyword will always match: for example, when used in the second section, it will match all possible users or groups, or when used in the third, all possible sources.
The NONE
keyword has the exact opposite effect of ALL
, and LOCAL
, which has sense only in the origins
section of the rule, will match every string which does not contain a ‘.’. Finally a very powerful keyword is EXCEPT
which allows us to specify exceptions to a set rule.
Some examples
The file provides some useful examples, let’s look at some of them. First of ALL we have the following:
- : ALL EXCEPT root : tty1
This line, would let us obtain the opposite result we have obtained before by modifying the /etc/securetty
file: first of all we have the -
sign, which means it is a deny
rule. In the next section, separated by a colon, we have ALL EXCEPT root
,which specifies that the rule must be applied to all users except root
, and in the third section, we see that the specified rule is valid only when someone tries to access from tty1
.
Another example, this time with multiple usernames:
-:wsbscaro wsbsecr wsbspac wsbsym wscosor wstaiwde:ALL
The rule forbids access to the wsbscaro, wsbsecr, wsbspac, wsbsym, wscosor and wstaiwde users from all sources (see the ALL
keyword in action)
Something more complex. This time the rule denies access to all users who are not member of the wheel group on local
logins:
-:ALL EXCEPT (wheel):LOCAL
Finally an example which specifies a rule for a remote login:
+ : root : 192.168.200.1 192.168.200.4 192.168.200.9
As we now should understand, this rule allows root
to access the system only from the specified ip addresses.
A test case
We can verify what we said above with a test case: let’s build a rule to deny access to egdoc
(my account on this system) from tty1
and append it at the end of the /etc/security/access.conf
file:
-:egdoc:tty1
Now, if we switch to tty1
and try to login, we obtain this rude response from the system:
Please notice that the order of the specified rules in the /etc/security/access.conf
file is really important, since the rules are evaluated in order of appearance.