Users and Permissions
Linux, like Unix before it, has always been designed as a multi-user operating system. This means that it is primordial to understand how users and groups work, how permissions are managed, and how they affect what users can do, how they tie into Django and Python, etc.
Hopefully, this chapter will help clarify these concepts.
Users and groups
Users and groups are used to manage permissions. Every user is identified by a username, and every group is identified by a groupname. Each username is linked to a numeric user ID (uid), and each groupname is linked to a numeric group ID (gid). Each ID should only be used by one user or group. User and group names are only used for convenience, while most kernel functions rely on numeric IDs for authorization and access control.
By convention, regular users have IDs starting from 1000
, while uids lesser than 1000
are restricted to system users. System users have no login, but can be used to run services like a database, web server, etc. Some common system users and groups could be www-data
, http
, or similar, depending on your distro and other factors.
Users belong to a primary group, but they can also belong to any number of supplemental groups which may provide them with extra permissions.
The root user
There is one special user, called root
, which has a special uid
and gid
of 0
. There is also typically a root
group. This user is commonly called a superuser, as they have all permissions. It should not be used regularly, but it can be used to manage users, files, packages, etc. For security purposes, you should not run services as root
.
Note that the root
user is the only user that can run services on reserved ports, which is all ports below 1024
. That means that it is common to start services as root
, and configure them to drop privileges.
Dropping privileges
If you start a privileged process, specifically one with the CAP_SETUID
capability, you can use a system call like setuid
to change the user ID of the process after it has started. This is commonly used to start services as root
so they can bind to restricted ports, then change to a user with lesser privileges. This helps increase security, since if there is some bug in some service, a hacker that exploits it could gain access to your server, but not as the root
user. Of course, it is still bad, so make sure you update your servers regularly, and try to isolate services as much as possible.
One example of a program that works this way is nginx
, which has a user username [group]
option. nginx
starts the master process as root, then uses username
for worker processes. Depending on your distro, the username may be www-data
or http
.
Privilege escalation
As previously mentioned, you should generally avoid logging in as root
, but rather you should escalate privileges from your regular user. You can do this using the sudo
command (superuser do), or the su
command (switch user).
For example, ls /root/
will likely give you a Permission denied error, while sudo ls /root/
will run the command as the root
user which will have permissions to list the directory contents. It is common to use sudo
to edit configuration files, manages users, install or update packages, etc. By default, sudo
will run as the root
user, but you may also run commands as a different user with sudo -u username command
.
Privilege escalation attacks
Note that hackers or certain users may attempt to gain elevated privileges if they can access your system. Privilege escalation can be a good tool to manage your server, but you also want to ensure that permissions are restricted as much as possible.
Configuration files
The most common and important configuration files for user management include:
/etc/passwd
: the user database file./etc/group
: the group database file./etc/shadow
: the secure user database file./etc/gshadow
: the secure group database file.
The shadow
and gshadow
files are only accessible by processes running as the root
user. The passwd
and group
files are readable by any user. The passwd
file used to contain the password hashes for all users, which allowed other users to brute force passwords. For better security, hashed passwords are now kept in the shadow
file.
Note that you should never edit those files directly, but you should rather use the commands which we will cover in a later chapter.
/etc/passwd/
The passwd
file is a plain-text database containing the following colon (:
) delimited fields:
The username
is the name the user uses to log in. It needs to be valid according to some rules. By convention, they are generally lower case. You can use your first name, first initial followed by your last name, first name followed by the first initial of your last name(s), etc.
As previously mentioned, storing the password
hash in this file is insecure. Most modern Unix and Linux systems now use a placeholder like x
to indicate that the password is set in the shadow
file.
The uid
is the numeric ID of the user. As mentioned, this should be equal or greater to 1000
for regular users. The gid
is the numeric ID of the user's primary group.
The gecos
field is an optional description of the user. It can contain their real name or contact information. It is named after the General Comprehensive Operating System.
The homedir
is the user's home directory. It is usually /home/username
for regular users.
The shell
is the default command interpreter for this user. Some example values may be /bin/bash
or /usr/bin/fish
.
/etc/group/
The group
file is a plain-text database containing the following colon (:
) delimited fields:
The groupname
is the name of the group. Some groups may be predefined by the distro packagers.
The grouppassword
is the password hash for the group. Like the passwd
file, it is insecure to set in this file. Furthermore, group passwords may be insecure as they may be shared with multiple users. As such, we will not be using them.
The gid
is the numeric ID for this group.
The users
field is a comma-separated list of group member usernames. This typically does not list the user if the entry refers to their primary group.
/etc/shadow/
The shadow
file is a plain-text database containing password information for all users. It contains the username, password hash, and password change policies. Please refer to the man page for more details.
/etc/gshadow/
The gshadow
file contains the shadowed password information for all groups. It contains the group name, optional password hash if you want users to be able to gain permissions of a group they are not members of, a list of administrator usernames, and a list of member usernames.
File permissions
File permissions will be covered in the Linux File System Layout chapter.
Users and Python
You can access user and group information for the current user using the os
module. Here are a few examples:
>>> import os
>>> os.getuid() # get the real UID for the current user
1000
>>> os.getgid() # get the real GID for the current user
1000
>>> os.geteuid() # get the effective UID for the current user
1000
>>> os.getegid() # get the effective GID for the current user
1000
>>> os.getgroups() # get the groups for the current user
[969, 998, 999, 1000]
>>> os.getlogin() # get the username for the current user
"username"
Here is one more example with dropping privileges. To do this, run Python as root with the sudo python
command.
>>> import os
>>> os.getuid()
0
>>> os.setuid(1000) # change the uid for the process to 1000
>>> os.getuid() # we no longer have root privileges
1000