A Step-by-Step Guide to Setting Up Permissions on Your Linux Web Server

A Step-by-Step Guide to Setting Up Permissions on Your Linux Web Server

Web server permissions: setting them right can be challenging, but setting them wrong can be disastrous. Of course, we don't want to grant a third party access to private files and folders or allow the execution of malicious code.

It's frustrating when your users encounter a 403 Forbidden error while visiting your website or trying to download a file. But trust me, the solution is never to 'just set the permissions to 777,' despite how often I've seen that advice online.

Want to secure the permissions of your Linux web server once and for all? Then this guide is for you!

A Quick Rundown

In Linux, the operating system can have many users. Each user can belong to multiple groups, and permissions determine what actions a given user or group can perform on a specific file or folder. These actions are read, write, and execute. The names are quite self-explanatory, but let's dive into what they actually mean:

For Files:

  • Read (r): View the contents of the file.
  • Write (w): Modify the contents of the file.
  • Execute (x): Run the file (e.g., a bash script).

For Directories:

  • Read (r): List the contents of the directory.
  • Write (w): Create, delete, or modify files within the directory.
  • Execute (x): Navigate (cd) into the directory. This means you can access the directory and perform actions on its contents, but not necessarily list them without read permission.

Each file and folder has three sets of these permissions:

  • The first set determines what the owner can do. By default, the owner of a file or folder is the user who created it. Normally, the owner has rwx (read, write, and execute) permissions.
  • The second set determines what other users in the same group as the owner can do. These permissions can be more restrictive. For example, you might want these users to be able to read and write the file but not execute it, resulting in rw- (the hyphen in place of the x means they lack that permission).
  • The third set determines what any other user can do. Perhaps you want anyone to only read a file (r--), or you might want to forbid all actions (---).

These three sets of permissions are expressed as a single concatenated string, such as rwxrw-r--.

Additionally, at the beginning of the string, you'll find a d if the item is a directory, or a - if it is not.

For example, the permissions of your /var/www/html/ directory might look like this: drwxr-xr-x. This means:

  • d indicates that it is a directory. Remember, executing a directory means being able to open the folder.
  • rwx means the owner can read, write, and execute.
  • r-x means users in the group can read and execute.
  • r-x means any other user can read and execute.

How to Change Owner and Group

To change the owner and group of a file or directory, use the chown command. For example, to change the owner of file.txt to username, run:

chown username file.txt

To change both the owner and the group at once, use a colon to separate them:

chown username:groupname file.txt

If you need to change the owner or group for an entire directory and its contents, add the -R option to apply changes recursively:

chown -R username:groupname /path/to/directory

Always double-check your commands and file paths before running them to avoid unintentionally altering critical system files.

How to Change Permissions

To modify file or directory permissions, use the chmod command. There are two common methods: numeric (octal) and symbolic.

Numeric Method:

Permissions are set using numbers:

  • 7 for rwx (read, write, execute)
  • 6 for rw- (read, write)
  • 5 for r-x (read, execute)
  • 4 for r-- (read only)
  • 0 for --- (no permissions)

For example, to set permissions for a folder so that the owner has full permissions and everyone else has read and execute, run:

chmod 755 my-folder/

Additionally, we can add the digit 2 before the permission numbers: 2755. This is used to set the setgid (Set Group ID) permission on the directory, which makes files created within the directory inherit the group of the directory, rather than the group of the user who created the file.

For instance:

chmod 2755 my-folder/

This ensures that files created inside my-folder/ will inherit the group ownership of the directory (www-data, for example), which is especially useful for shared directories where multiple users need to write to the same location but maintain consistent group ownership.

Symbolic Method:

This method allows you to add or remove specific permissions:

  • + to add a permission
  • - to remove a permission
  • = to set the exact permission

For example, to add execute permission for the group on file.txt, run:

chmod g+x file.txt

Similarly, to remove write permission for others:

chmod o-w file.txt

To set the setgid (set group identity) permission on a directory, you can use the g+s flag. This ensures that files created inside the directory will inherit the directory's group:

chmod g+s my-folder/

For directories, if you need to change permissions for all contained files and subdirectories, use the -R option:

chmod -R 755 my-folder/

These commands help ensure that your files and directories have the correct permissions to maintain both functionality and security.

The Right Permissions for your Website Files

Now that we're all on the same page, let's tackle the big question: What permissions should my website's files and folders have?

If you're using Nginx or Apache to serve your site, you're likely aware that these web servers run under their own user accounts. Typically, this user is called www-data, and it also has a corresponding group named www-data. The web server needs read access to files and folders that should be publicly accessible. In some cases, it also requires write access to certain subdirectories—such as when a PHP process needs to log data or when visitors are allowed to upload files to a temporary folder.

When you connect to your server via SSH, you're usually using your own user account. This could be the superuser root, or a user you've created for yourself, like nico. You might create a directory for your new side project, such as /var/www/side-project, and then add files manually or pull them from a Git repository.

Here's the issue: if the web server user (www-data) doesn't have permission to read a file owned by your user (nico), the server will return an error when trying to access it.

How can we fix that? We can adjust the permissions of the directory containing all your websites (/var/www) and set the following:

  • Set your user (nico) as the owner.
  • Set the web server group (www-data) as the group.

Then, determine the following permissions:

  • The owner can read, write, and execute files and directories.
  • Any user in the group can read files, and read and execute directories.
  • Any other user does not have any permission over the files and directories.

This setup allows Nginx or Apache (www-data) to read and serve files reliably, maintains security by preventing unauthorized access, and allows you (nico) to create, edit, and delete files without worrying about messing up your website.

Now, let's look at how we can achieve this setup, ensuring new files and directories inherit the correct permissions automatically, so that next time you create a folder for a new site, you won't have to adjust anything manually!

Step 1: Assign Ownership

First, let's assign nico as the owner and www-data as the group for all files and directories inside /var/www, recursively:

sudo chown -R nico:www-data /var/www

On some systems, the web server user might be different (e.g., www-html or apache). If that's the case, simply adjust the command to reflect the correct user and group.

Step 2: Configure Permissions For Existing Files and Folders

Next, define the permissions. Directories and files require distinct settings:

sudo find /var/www -type d -exec chmod 2750 {} \;
sudo find /var/www -type f -exec chmod 0640 {} \;

Directories: 2750

  • The owner nico can read, write, and execute.
  • Users in the www-data group can read and execute.
  • Others have no permissions.

The leading 2 (setgid bit) ensures new files and subdirectories inherit the www-data group. For instance, if you're in /var/www and create a directory with mkdir my-site, it will automatically belong to the www-data group. Likewise, when you create a file with touch log.txt, it will inherit the same group.

Files: 0640

  • The owner nico can read and write.
  • Users in the www-data group can only read.
  • Others have no permissions.

These are good defaults but won't allow you to execute files. If you need to execute a script, manually add the execute permission (e.g. using chmod +x my-file).

If you want to allow any user to enter directories and read files, you can opt for 2775 for directories and 0644 for files.

Step 3: Use umask to Set Permissions for New Files and Directories

The setgid bit (indicated by the leading 2 in 2750) ensures that new subdirectories and files inherit the parent directory's group, but it does not modify their permission bits.

In Linux, files and directories are initially created with default permissions—typically 777 for directories and 666 for files.

These permissions are quite permissive but are modified by a default value called umask. The umask (user file creation mask) specifies which permissions to remove from these defaults when new files and directories are created.

By default, umask is set to 022. You can check it by running the command umask in your terminal. What does 022 mean?

  • The first digit (0) has no effect.
  • The second digit (2) removes write permission for the group.
  • The third digit (2) removes write permission for others.

For new directories, it turns 777 into 755 (rwxr-xr-x). For new files, this default umask turns 666 permissions into 644 (rw-r--r--).

If those are the permissions you configured in the previous section, then you're all set! But if you went for the more restrictive permissions that remove all permissions for other users (750 and 640), you will need to tweak the last digit of umask.

Which digit should we use? Well, if 7 allows all permissions, then 7 for umask means removing all those permissions. Remember, umask defines the permissions that won't be assigned by default. Therefore, we need to set the umask value to 027.

  • The first digit (0) has no effect.
  • The second digit (2) removes the write permission for the group.
  • The third digit (7) removes the read, write, and execute permissions for others.

Add the following line to your ~/.bashrc or ~/.zshrc:

umask 027

Then, apply the change with:

source ~/.bashrc  # or source ~/.zshrc

Step 4: Validate the Configuration

Verify that everything is set correctly:

ls -l /var/www

Expect to see:

  • Directories: drwxr-s--- (2750), with the s indicating setgid.
  • Files: -rw-r----- (0640).
  • Ownership: nico:www-data.

If discrepancies appear, reapply the ownership or permissions commands from earlier steps to correct them.

Conclusion

Today, we've covered all the essentials—understanding permission strings, setting the right ownership for your files, and ensuring your web server can function securely without exposing vulnerabilities.

Server security isn't just a switch you flip; it takes attention and care. So don't skip this step! Take a few minutes to double-check your setup, make any necessary tweaks, and you'll sleep better knowing your server is secure.

Until next time!