By Alexandru Andrei, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud's incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.
Linux-based operating systems are multi-user environments. Since it's expected that multiple users will have access to the same system, basic security mechanisms are implemented. In this tutorial, we will analyze how the level of access to files and directories is decided, based on a set of permissions that we can adjust with the chmod
utility. Depending on the rules that are applied, we are able to allow or deny reading, writing and executing specific files. Similarly, it lets us decide which users should be able to browse particular directories and add/remove content to/from them. There are also a few special modes we can set, such as setuid, setgid, sticky and restricted deletion flag, which will be detailed in the following sections.
Even if your particular use case doesn't involve multiple users having access to the operating system, i.e., only you will be able to log in and browse files on your Elastic Compute Service (ECS) instance, processes such as the Apache web server still run under a dedicated username and file/directory permissions play an important role. Being a service that is accessed remotely (i.e., by other people on the Internet), incorrect permissions may give the public free access to files which are meant to be private, or, they may allow an attacker to exploit a vulnerability and then modify content of your website's code. Correct permissions, in most cases, will prevent or at least significantly reduce the likelihood of such scenarios.
If you want to learn by doing and follow all of the steps in this tutorial, launch a new ECS instance and use Debian as the operating system. Other Linux distributions such as CentOS, OpenSUSE or RedHat might have slight variations in default users/groups added to the system, different locations for configuration files, etc., which means you might have to adapt some of the commands. Otherwise, if you intend to only read and learn the theory, distribution choice isn't important since chmod
itself is pretty much identical on all Linux-based operating systems.
Launch your instance, connect to it with an SSH client and log in as root.
To understand file/directory permissions, we will first have to go over the basic concepts.
You can think of users on a Linux system as a sort of user accounts. Every user must belong to a primary group and, optionally, can belong to one or more additional groups. There's a differentiation between regular users and system users. The first type will usually have a home directory, a default login shell and will be able to log in to the system, either locally or from remote locations (through SSH). System users are usually intended to run daemons and have no home directory, login shell or password associated so that local or remote logins are impossible. The purpose of this approach is to limit access as much as possible for certain processes (usually services that accept inbound connections from the Internet, since they are considered more vulnerable).
In some scenarios, you will want to give multiple users the same level of access to the same resource. Let's say you want a team to be able to edit files of a web application stored on your ECS instance. Since a directory can be owned by only one user, you would have to let the entire team log in as that user, which means they would have to use the same credentials, share the same password, etc. This is not ideal and it's where groups can help. You can have multiple users (user1, user2, user3) belong to the same group (webeditor). Now, everyone can log in independently, with their own credentials. You can then make the "webeditor" group the owner of the directory and files that make up your web application. Finally, you can add permissions to allow anyone in the "webeditor" group to read and write content.
Every file and directory is owned by a user and by a group. Only the user owner can change permissions (user id of the person logged in must match the user id stored as the file/directory owner). The only exception to this rule is the root user which is allowed to adjust the permission of any object, regardless of the owner. You automatically own the files that you create and only the root user can change the user owner of a file. The group owner however can be changed by any user, under these conditions: the user owns the file and is part of the group that will become the new group owner. Example: "user1" is part of primary group "user1" (by default, every user manually added to the system will be part of a group that has the same name). "user1" is also part of additional group "webadmin". With the chown
command, "user1" can change the group owner of a file to either "user1" or "webadmin" but not to another group such as "ntp". Since this may sound confusing at first, let's go through a practical example.
Create a new user:
adduser --disabled-login --gecos '' user1
Add the user to two supplementary groups, "games" and "users":
usermod -aG games,users user1
Switch to this user's environment:
su - user1
Create a file:
touch file1
To see the current owner of the file:
ls -l
The output of the command will look like this:
user1@debian:~$ ls -l
total 0
-rw-r--r-- 1 user1 user1 0 Sep 5 22:56 file1
We can see that the file is owned by user "user1" (first field) and group "user1" (second field). Let's change the group owner:
chown :games file1
Now ls -l
will show:
user1@debian:~$ ls -l
total 0
-rw-r--r-- 1 user1 games 0 Sep 5 22:56 file1
Since "user1" is also part of the "users" group, we can also:
chown :users file1
But if we try to change the group owner to "staff":
chown :staff file1
Since "user1" is not part of that group, we will get this message:
user1@debian:~$ chown :staff file1
chown: changing group of 'file1': Operation not permitted
The syntax of the chown
command is: chown user:group /path/to/directory/or/file
. As you can see from the examples above, the username can be omitted if we only need to change the group owner, by passing :group
as a parameter.
To recursively change owners (perform the same action on all files and subdirectories contained in a directory) you can use the -R
parameter in a command such as chown -R user:group /path/to/directory
.
Let's see the permissions and owners of every object stored in the /var
directory:
ls -l /var/
The output may look like this:
root@debian:~# ls -l /var/
total 36
drwxr-xr-x 2 root root 4096 Sep 4 16:28 backups
drwxr-xr-x 9 root root 4096 Oct 25 2017 cache
drwxr-xr-x 31 root root 4096 Oct 25 2017 lib
drwxrwsr-x 2 root staff 4096 Jul 13 2017 local
lrwxrwxrwx 1 root root 9 Oct 25 2017 lock -> /run/lock
drwxr-xr-x 6 root root 4096 Sep 4 16:28 log
drwxrwsr-x 2 root mail 4096 Oct 25 2017 mail
drwxr-xr-x 2 root root 4096 Oct 25 2017 opt
lrwxrwxrwx 1 root root 4 Oct 25 2017 run -> /run
drwxr-xr-x 4 root root 4096 Oct 25 2017 spool
drwxrwxrwt 2 root root 4096 Sep 4 16:28 tmp
Let's break down the following line: drwxrwsr-x 2 root mail 4096 Oct 25 2017 mail
. In the first field, drwxrwsr-x
, the first letter, d
signifies that the object is a directory. If the first character would be -
it would denote a file and l
would indicate a symbolic link. After that, we have the permissions: rwxrwsr-x
. The first three letters denote user (owner) permissions, the next three group permissions and the last three, permissions for all of the other users on the system. The order is always rwx
, rwx
, rwx
for user, group, other, and where you will find a -
instead of a letter it means that particular permission is non-existent/denied. x
may sometimes be replaced by s
, S
, t
or T
which indicates special types of flags have been set.
Let's see what the letters mean. For files:
r
-- readablew
-- writablex
-- executable (for programs/scripts)-
-- permission denied (r-x
would denote that you can read and execute file but not write to it, rw-
that you can read and write but not execute)s
-- File is executable and will set user (setuid) or group ID (setgid) on execution. The process will execute with the file's user owner ID and/or group owner ID, regardless of the user that launched the program, e.g., if the user nobody
runs a file with properties such as -rwsr-xr-x 1 root root 40536 May 17 2017 /bin/su
, su
will run as the root user.S
-- File has set user/group ID on execution enabled but is not executable (although possible to set permissions in such a way, it serves no purpose).t
or T
-- Sticky bit; can be set on files but does nothing on Linux (on other operating systems it may have some effects).For directories, permissions are interpreted in a slightly different way:
r
-- Contents can be listed with a command such as ls name_of_directory
. Always used in conjunction with x
to be useful. A readable but not executable directory can be listed with a command such as ls name_of_directory
but the contents themselves cannot be read or written to and programs cannot be run, even if the readable, writable, executable bit is set on those files.w
-- You can add files and subdirectories, delete or rename contents within.x
-- You can "execute" directory contents, meaning you can read (readable) files, write to those files (if the files themselves have the write permission enabled) and run programs (if executable bit is set on them).To more easily remember the effects of these permissions you can think that they focus more on the structure of a directory rather than the objects it contains: with r
you can read the structure, see the table of contents, with w
you can change the structure and with x
you can execute/take action (read, write, run) on any part of that structure.
s
-- Set group ID: the directory is executable and every file/subdirectory created in it will automatically inherit the group owner. From our example above /var/mail
has the following permissions: drwxrwsr-x 2 root mail 4096 Oct 25 2017 mail
. This means that any file/directory that any user creates there will automatically be owned by the "mail" group (even if the user doesn't belong to this group). Although s
can also be set for user permissions, instead of group, it has no effect on Linux. The files will still be owned by the user that created them, not by the user owning the directory.S
-- The directory has the set group ID/set user ID flag enabled but is not executable.t
-- Restricted deletion flag enabled and directory is executable by other users. This is useful on directories shared between multiple users. Normally, whoever can write content in a directory, can also delete it, even if they don't own that content. The restricted deletion flag prevents that and allows users to delete only content that they own.T
-- Restricted deletion flag enabled but directory is not executable by other users.Make sure you're still logged in as a regular user, for example "user1" we created in the previous section. The root user can bypass permissions, making it harder to notice the effects of restrictions. Let's create a few directories and files, to learn how to use chmod
on them:
mkdir directory
mkdir directory/subdirectory
touch directory/file{1..3}
Let's break down one of the syntax forms chmod
has: chmod [ugoa][-+=][rwxXst] /path/to/file/or/directory
. u
stands for user, to change user permissions. g
is for group and o
is for others. a
means all, altering permissions in the same way for all three categories, user, group and others. -
removes permissions and +
adds, leaving unmentioned flags unchanged, =
sets them to exactly the values specified and removes all unmentioned permissions. rwxXst
are the permissions we have described in the previous section (X
will be explained in an example below). It's easier to understand when we see the effects:
ls -l
We should get an output similar to:
user1@debian:~$ ls -l
total 4
drwxr-xr-x 3 user1 user1 4096 Sep 5 23:36 directory
-rw-r--r-- 1 user1 users 0 Sep 5 22:56 file1
"file1" can be read by other users. Let's say we want to make it private:
chmod o-r file1
Now the read permission should be removed for other users:
ls -l
Output:
user1@debian:~$ ls -l
total 4
drwxr-xr-x 3 user1 user1 4096 Sep 5 23:36 directory
-rw-r----- 1 user1 users 0 Sep 5 22:56 file1
If we want other users to be able to read, write and execute the file:
chmod o+rwx file1
Let's list files again:
ls -l
Output:
user1@debian:~$ ls -l
total 4
drwxr-xr-x 3 user1 user1 4096 Sep 5 23:36 directory
-rw-r--rwx 1 user1 users 0 Sep 5 22:56 file1
Now if we want to get back to the same way it was, readable by other users, we would have to remove the w
and x
permissions with o-wx
or, we can make use of the =
sign:
chmod o=r file1
New output of ls -l
:
user1@debian:~$ ls -l
total 4
drwxr-xr-x 3 user1 user1 4096 Sep 5 23:36 directory
-rw-r--r-- 1 user1 users 0 Sep 5 22:56 file1
Multiple types of permissions can be set simultaneously, by separating them with commas:
chmod u=rwx,g+w,o= file1
ls -l
output:
user1@debian:~$ ls -l
total 4
drwxr-xr-x 3 user1 user1 4096 Sep 5 23:36 directory
-rwxrw---- 1 user1 users 0 Sep 5 22:56 file1
We also learned how to clear all permissions, by using o=
. If you don't specify any values after the =
sign, all permissions of that type are removed.
Another way to specify permissions, which can be faster to type, is by using octal values. This is done by considering that the r
, w
, x
flags are either ON (1) or OFF (0) and then converting the resulting binary value (base 2) to an octal value (base 8).
rwx | rwx | rwx | rwx | rwx | rwx | rwx | rwx | |
---|---|---|---|---|---|---|---|---|
Binary Value | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
Octal Value | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
Resulting Permission | --- | --x | -w- | -wx | r-- | r-x | rw- | rwx |
So instead of writing a command such as chmod u=rwx,g=rx,o= file1
to get the resulting permission rwxr-x---
, we can simply write:
chmod 750 file1
And ls -l
will confirm our change:
user1@debian:~$ ls -l
total 4
drwxr-xr-x 3 user1 user1 4096 Sep 5 23:36 directory
-rwxr-x--- 1 user1 users 0 Sep 5 22:56 file1
To enable the setuid flag for a file:
chmod u+sx file1
u+s
is actually what enables setuid, but we will also have to make the file executable if it isn't already so, otherwise the setuid flag wouldn't have much use. To enable the set group ID flag, we just change u
to g
: chmod g+sx file1
.
The same commands hold true for directories, but in their case we also have the restricted deletion flag we can make use of:
chmod +t directory
New state of files/directories:
user1@debian:~$ ls -l
total 4
drwxr-xr-t 3 user1 user1 4096 Sep 5 23:36 directory
-rwsr-s--- 1 user1 users 0 Sep 5 22:56 file1
Just like with chown
, we can add the -R
parameter to recursively apply changes to everything contained in a directory:
chmod -R o= directory
And we can see that all permissions for other users have been disabled:
user1@debian:~$ ls -l directory/
total 4
-rw-r----- 1 user1 user1 0 Sep 5 23:36 file1
-rw-r----- 1 user1 user1 0 Sep 5 23:36 file2
-rw-r----- 1 user1 user1 0 Sep 5 23:36 file3
drwxr-x--- 2 user1 user1 4096 Sep 5 23:36 subdirectory
It's also possible to apply the same changes to all three types of permissions (user, group and other) by using a
(meaning all):
chmod -R a-x directory/*
Here, we used directory/*
instead of directory/
, to apply actions on contents but not on the directory itself. Now that the executable flag is removed from all objects in "directory", we can exemplify another useful parameter of the chmod
command.
ls -l directory
will show us that all contents are non-executable:
user1@debian:~$ ls -l directory
total 4
-rw-r----- 1 user1 user1 0 Sep 6 00:28 file1
-rw-r----- 1 user1 user1 0 Sep 6 00:28 file2
-rw-r----- 1 user1 user1 0 Sep 6 00:28 file3
drw-r----- 2 user1 user1 4096 Sep 6 00:28 subdirectory
Which is problematic for directories since now creating files in "subdirectory" will fail:
touch directory/subdirectory/file
Output:
user1@debian:~$ touch directory/subdirectory/file
touch: cannot touch 'directory/subdirectory/file': Permission denied
It's easy to just make "subdirectory" executable again but what if we had hundreds of files and subdirectories? We couldn't just run chmod -R u+x directory
since that would also make files executable, not only directories. To recursively add the executable flag only to directories, but not files, we can use capital X
, like in the following command:
chmod -R u+X directory/
And ls -l directory/
will confirm that the executable flag has only been added to "subdirectory":
user1@debian:~$ ls -l directory/
total 4
-rw-r----- 1 user1 user1 0 Sep 6 00:28 file1
-rw-r----- 1 user1 user1 0 Sep 6 00:28 file2
-rw-r----- 1 user1 user1 0 Sep 6 00:28 file3
drwxr----- 2 user1 user1 4096 Sep 6 00:28 subdirectory
Automatic Security Upgrades with Unattended-upgrades Package
2,599 posts | 762 followers
Followfrancisndungu - December 12, 2018
francisndungu - August 3, 2018
Alex - October 16, 2018
francisndungu - October 26, 2018
Alibaba Cloud Community - December 31, 2021
Alibaba Clouder - July 4, 2018
2,599 posts | 762 followers
FollowElastic and secure virtual cloud servers to cater all your cloud hosting needs.
Learn MoreAn encrypted and secure cloud storage service which stores, processes and accesses massive amounts of data from anywhere in the world
Learn MoreSecure your cloud resources with Resource Access Management to define fine-grained access permissions for users and groups
Learn MoreMore Posts by Alibaba Clouder