Permissions in Linux can be a bit confusing. For every directory and file, there are permissions that can be set informing what users can perform operations on them, as well as what operations those users can take.
Users can perform read (r), write (w) and execute (x) operations on files/directories. Here's how the three permission types breaks down when applied to directories and files:
read- ability to read contents of a directory
write- ability to rename or create a new file/directory within a directory (or delete a directory)
execute- ability to
cdinto a directory
read- ability to read a file
write- ability to edit/write to a file (or delete a file)
execute- ability to execute a file (such as a bash command)
The other half of this is users and groups. For any file and directory, we can define how users (u), groups (g) and others (o) can interact with a directory or file. Here's how that breaks down:
User- The permission for owners of a file or directory
Group- The permissions for users belonging to a group. A user can be part of one or more groups. Groups permissions are the primary means for how multiple users can read, write or execute the same sets of files
Other- The permissions for users who aren't the user or part of a group assigned to a file or directory
To illustrate this, let's check the permissions of a directory, for example
$ ls -la /var/www drwxr-xr-x 2 root root 4096 May 3 19:52 . # Curent Directory drwxr-xr-x 12 root root 4096 May 3 19:46 .. # Containing Directory -rw-r-xr-- 1 root root 13 May 3 19:52 index.html # File in this Directory
How do these columns of information break down?
drwxr-xr-x- User/Group/Other Permissions. The preceding "d" denotes this as a directory. Lacking a "d" means it's a file.
2- This is the number of "hard links" to the file or directory
root root- The User and Group assigned to the file or directory
4096- The size of the file/directory in bytes
May 3 19:52- last modified (or created) data/time
.- The file name. A period (.) is the current directory. Two periods (..) is the directory one level up. Otherwise this will show a file or directory name.
Let's go over the permission attributes - that first column of information:
For any permission attribute set, the first slot denotes if it's a directory (d), link (l) (as in symbolic link) or file (-).
Then each next three characters denotes the read, write and execute permissions for users groups and others, respectively.
Let's take the permissions
d- denotes it's a directory
rwx- The user has read, write and execution permissions
r-x- The group can read and execute, but not write
r-x- The same for others. Since this is a directory, this means users can read the directory but not modify it or its containing files
Next, let's analyze
-- denotes it's a file
rw-- denotes users can read, write but not execute the file
r-x- group members can read the file or execute it
r--- others can only read the file
We can change a file or directory permissions with the
Here's some chmod information and a breakdown:
chmod [-R] guo[+-]rwx /var/www
-R- Change permissions recursively (if its a directory)
u- perform operation on the user permissions
g- perform operation on the group permissions
o- perform operation on the other permissions
+- add permission
-- remove permission
Permission types to set
r- add or remove read permissions
w- add or remove write permissions
x- add or remove execute permissions
So, for example, let's create the
/var/www directory as user root and set its permissions.
# Create directory as root sudo mkdir /var/www # Change to owner/group www-data: sudo chown www-data:www-data /var/www # Set permissions so user and group has permissions, but not other: sudo chmod ug+rwx /var/www # User and Group have all permissions (+rwx) sudo chmod o-rwx /var/www # Other has no permissions (-rwx) sudo chmod o+rx /var/www # Other can read and `cd` into the directory (+rx)
This is useful if you have a user for deployment on your server. If the deployment user is part of the group
www-data, that user will have permissions to add/update files within the
Note that files created by a user are set to belong to that users username and main group (users belong to a main and secondary groups). This means that after creating/deploying files, we'll likely need to set their permissions properly. For example, after a deployment to
/var/www, the deployment user should set the group and group permissions of all new files within
/var/www/ so the
www-data group and read/write to them, and any "others" can only read them.
The other half of managing permissions is managing users and what groups they belong to.
Every user created by default belongs to a user and group of the same name. Users can belong to one primary group, and then can be added to other groups (plural) as their secondary groups.
The primary group is what files/directories are assigned when a user creates a new file or directory. (Their username is of course the user assigned to those same files/directories).
We can find a list of users created in the
$ vim /etc/passwd
This will show us the following information in colon-separated columns:
- Password ("x" meaning the user has an encrypted password)
- User ID (UID)
- Group ID (GID)
- User Information (extraneous notes)
- Home Directory
- Command/Shell used by the user
For more information on this list, including some notes on the UID/GID's, see this article.
Let's create a new user to use for deployments. We'll name this user "deployer".
$ sudo adduser deployer
This will do some setup and ask you for a password for this user. This might also ask you for the user's full name and some other not-necessarily-important information.
If we check out
/etc/passwd again, we'll see a line similar to this:
In the above example, our user "deployer" has a UID of 1001 and GID (the group deployer) of 1003.
We can act as this user by running the command:
$ sudo su - deployer
Then we can type in
groups to see what groups we are part of:
$ groups deployer
If you're following along, run the
exit command to go back to your sudo user (
vagrant in my case, since I'm writing this article using a Vagrant server).
Let's set our
deployer user to have a secondary group of
$ sudo usermod -G www-data deployer
-G (upper-case "G") assigns the user
deployer the group
www-data as a secondary group. This means that if a directory or file is part of the
www-data group and allows group members permissions to read/write to that file, then our user
deployer can read/modify it. Our
deployer user can deploy to
Alternatively, I often make my deploy users primary group
www-data, so that new files/directories it creates will be created with the group
www-data automatically. Otherwise they are created with group
deployer and we need to do the extra step of changing that and updating group permissions.
In that case, we can run:
$ sudo usermod -g www-data deployer
-g (lower-case "g") will assign the user
deployer the group
www-data as its primary group. This has the benefit that any files/directories created by this user will have the
www-data group assigned to it, and we can not worry about changing the group of files/directories.
So those steps, including creating a user and assigning it the primary group
$ sudo adduser deployer # Fill in user info and password $ sudo usermod -g www-data deployer # Assign group www-data (primary)
Then we can make sure our web files are in group
www-data and ensure group members have proper permissions:
$ sudo chgrp -R www-data /var/www $ sudo chmod -R g+rwx /var/www
On a new server, you want to turn off the ability for user
root to login over ssh:
$ sudo vim /etc/ssh/sshd_config # Edit the file controlling ssh login > PermitRootLogin no # Change from yes $ sudo reload ssh
If you create a new user who needs sudo privileges (but isn't the "root" user), you can assign sudo privileges in a few ways.
In Ubuntu, you can add the user to group "sudo":
sudo usermod -G sudo someusername
Otherwise you often need to use
$ visudo # As root user
Find a section "user privilege specification" and grant your new user all permissions:
# User privilege specification root ALL=(ALL) ALL someusername ALL=(ALL) ALL # Add your user here
Save and Exit there and that user will have sudo privileges!
You may notice some fun things in there. For example, we can setup a group which allows users assigned to it have passwordless-sudo abilities. This is what Vagrant uses for its
# Members of the admin group may gain root privileges %admin ALL=(ALL) NOPASSWD:ALL
Any user assigned the
admin group will have passwordless sudo abilities.
This is how Ubuntu assigns "normal" sudo privileges to users. It defines the "sudo" group one that has sudo privileges, so we can assign sudo privileges based on groups:
# Allow members of group sudo to execute any command %sudo ALL=(ALL:ALL) ALL
Processes (programs) are actually run as specific users and groups as well. This means we can regulate what processes can do to the system using the same means as file/directory permissions.
Core processes which need system access are often run as user root. However some run as user root, but then spawn processes as other users.
For example, Apache is started as user root. However, the workers it spawns is set by the User and Group settings in the Apache configuration. In Ubuntu, this is often user
www-data. This gives Apache the ability to do things like listen to port 80 (requires root privileges), but also more safely spawn processes which (hopefully) cannot perform malicious operations on the server.