dotlinux guide

Understanding Linux Permissions and Security from the Command Line

In the Linux ecosystem, file and directory permissions are the first line of defense for system security. They control who can access, modify, or execute files, ensuring that sensitive data remains protected and users operate within their intended boundaries. Whether you’re a system administrator, developer, or casual Linux user, mastering permissions is critical to maintaining a secure and functional system. This blog demystifies Linux permissions, starting with fundamental concepts, moving through practical command-line tools, and concluding with best practices to harden your system. By the end, you’ll be equipped to audit, modify, and enforce permissions like a pro.

Table of Contents

  1. Fundamental Concepts: Ownership and Permission Types
  2. Reading Permissions: Decoding ls -l Output
  3. Modifying Permissions with chmod
  4. Changing Ownership with chown and chgrp
  5. Special Permissions: SUID, SGID, and Sticky Bit
  6. Common Use Cases and Scenarios
  7. Best Practices for Security
  8. Conclusion
  9. References

Fundamental Concepts: Ownership and Permission Types

Linux permissions are based on two core ideas: ownership and permission levels.

Ownership: User, Group, and Others

Every file/directory in Linux is owned by:

  • A user (the primary owner, e.g., alice).
  • A group (a collection of users, e.g., developers).
  • Others (all users not in the owner or group categories).

Permission Types: Read, Write, Execute

Permissions define what actions each ownership category can perform. There are three basic types:

PermissionSymbolDescription
ReadrView file contents or list directory contents (for directories).
WritewModify file contents or add/delete files in a directory (for directories).
ExecutexRun a file as a program or access files/subdirectories in a directory.

File vs. Directory Permissions

Permissions behave differently for files and directories:

  • Files: r allows reading content, w allows editing, x allows execution (e.g., scripts, binaries).
  • Directories: r allows listing contents (e.g., ls dir), w allows creating/deleting files, x allows accessing files/subdirectories (even if you can’t list them).

Reading Permissions: Decoding ls -l Output

To view permissions for a file or directory, use ls -l (long listing). Here’s an example output:

-rwxr-xr-- 1 alice developers 1234 Jan 1 12:00 script.sh

Let’s break this down:

ComponentMeaning
-rwxr-xr--Permission string (10 characters total).
1Number of hard links.
aliceOwner (user).
developersGroup.
1234Size (in bytes).
Jan 1 12:00Last modified timestamp.
script.shFile/directory name.

The Permission String

The first 10 characters (-rwxr-xr--) encode:

  • 1st character: File type (- for regular file, d for directory, l for symlink).
  • 2-4th characters: Permissions for the owner (u: rwx).
  • 5-7th characters: Permissions for the group (g: r-x).
  • 8-10th characters: Permissions for others (o: r--).

Modifying Permissions with chmod

The chmod (change mode) command modifies permissions. It supports two syntaxes: symbolic (human-readable) and octal (numeric).

Symbolic Syntax

Symbolic mode uses u (user), g (group), o (others), a (all), and operators (+ add, - remove, = set exactly).

Syntax:

chmod [ugoa][+-=][rwx] file/directory

Examples:

  • Give the owner read/write/execute (rwx), group read/execute (rx), and others no permissions:
    chmod u=rwx,g=rx,o= script.sh  # Result: -rwxr-x---
  • Add execute permission for all users:
    chmod a+x script.sh  # Result: -rwxr-xr-x (if previously -rw-r--r--)
  • Remove write permission for the group:
    chmod g-w script.sh  # Result: -rwxr--r-- (if previously -rwxrwxr--)

Octal Syntax

Octal mode uses 3-4 digits (0-7) to represent permissions for user, group, and others. Each digit is a sum of:

  • 4 (read), 2 (write), 1 (execute).

Common octal values:

OctalPermissionDescription
7rwxRead, write, execute
6rw-Read, write
5r-xRead, execute
4r--Read only
0---No permissions

Examples:

  • Set user: rwx (7), group: rx (5), others: r-- (4):
    chmod 754 script.sh  # Result: -rwxr-xr--
  • Restrict a sensitive file to owner-only read/write:
    chmod 600 ~/.ssh/id_rsa  # Critical for SSH security!
  • Make a directory readable/writable/executable by owner, read/execute by group:
    chmod 750 projects/  # Result: drwxr-x---

Changing Ownership with chown and chgrp

To modify the owner or group of a file/directory, use chown (change owner) or chgrp (change group).

chown: Change Owner and/or Group

Syntax:

chown [options] user:group file/directory

Examples:

  • Change owner to bob and group to devs:
    sudo chown bob:devs report.pdf
  • Change only the owner (group remains unchanged):
    sudo chown alice script.sh
  • Change only the group (use : before the group):
    sudo chown :testers script.sh

chgrp: Change Group Only

A simpler alternative to chown :group:

chgrp developers project/

Notes:

  • Use sudo to change ownership of files you don’t own (e.g., system files).
  • Recursively change ownership of directories and their contents with -R:
    sudo chown -R bob:devs /home/bob/projects/

Special Permissions: SUID, SGID, and Sticky Bit

Beyond the basic rwx, Linux supports three special permissions that add advanced functionality (and security risks if misused).

SUID (Set User ID)

  • Symbol: s (replaces the user’s x permission, e.g., -rwsr-xr-x).
  • Behavior: When a user executes the file, it runs with the owner’s privileges (not the user’s).
  • Use Case: Critical binaries like passwd (allows users to modify /etc/passwd without root access).

Example: Set SUID on passwd (already set by default):

ls -l /usr/bin/passwd  # Output: -rwsr-xr-x 1 root root ... passwd

Risk: Never set SUID on scripts or untrusted binaries—an attacker could exploit it to gain elevated privileges!

SGID (Set Group ID)

  • Symbol: s (replaces the group’s x permission, e.g., -rwxr-sr-x).
  • Behavior:
    • For files: Executes with the group’s privileges.
    • For directories: New files created in the directory inherit the directory’s group (instead of the user’s primary group).

Examples:

  • Enable SGID on a shared directory so all new files inherit the devs group:
    chgrp devs shared_docs/
    chmod g+s shared_docs/  # Now drwxr-sr-x
  • Verify: New files in shared_docs/ will belong to devs, not the creator’s group.

Sticky Bit

  • Symbol: t (replaces others’ x permission, e.g., drwxrwxrwt).
  • Behavior: In a directory with the sticky bit, only the owner of a file (or root) can delete it—even if others have write access.

Example: /tmp uses the sticky bit to prevent users from deleting each other’s files:

ls -ld /tmp  # Output: drwxrwxrwt 10 root root ... /tmp

Set the sticky bit:

chmod +t shared_files/  # Result: drwxrwxrwt

Octal Notation for Special Permissions

Add a 4th leading digit to octal chmod commands:

  • 4 = SUID, 2 = SGID, 1 = Sticky Bit.

Examples:

  • Set SUID on passwd (octal 4755 = SUID + user:7, group:5, others:5):
    sudo chmod 4755 /usr/bin/passwd
  • Set SGID on a directory (octal 2775 = SGID + user:7, group:7, others:5):
    chmod 2775 shared_docs/
  • Set sticky bit on /tmp (octal 1777 = Sticky + user:7, group:7, others:7):
    sudo chmod 1777 /tmp

Common Use Cases and Scenarios

1. Securing Web Server Files

For a web server (e.g., Nginx/Apache), restrict config files to root and limit public files to read-only:

# Owner: root, group: www-data, permissions: 640 (root read/write, www-data read)
sudo chown root:www-data /etc/nginx/nginx.conf
sudo chmod 640 /etc/nginx/nginx.conf

# Public HTML files: read-only for all, no execute
chmod 644 /var/www/html/*.html

2. Shared Team Directories

Use SGID to ensure new files in a team directory inherit the devs group:

mkdir -p /opt/team_projects
chgrp devs /opt/team_projects
chmod g+s /opt/team_projects  # SGID: new files inherit group "devs"
chmod 770 /opt/team_projects  # Owner/group: read/write/execute; others: none

3. Finding World-Writable Files (Security Risk)

Audit for files writable by “others” (a common attack vector):

# Find world-writable files (excluding /proc and /sys)
sudo find / -type f -perm -o+w -ls 2>/dev/null

4. Setting Default Permissions with umask

umask (user file-creation mode mask) defines default permissions for new files/directories. It subtracts values from the base permissions:

  • Base for files: 666 (rw-rw-rw-).
  • Base for directories: 777 (rwxrwxrwx).

Common umask values:

  • 022 (default): New files = 644 (rw-r--r--), directories = 755 (rwxr-xr-x).
  • 077 (secure): New files = 600 (rw-------), directories = 700 (rwx------).

Set umask temporarily:

umask 077  # New files will be owner-only

Set permanently: Add umask 077 to ~/.bashrc (user-specific) or /etc/profile (system-wide).

Best Practices for Security

1. Principle of Least Privilege

Never grant more permissions than needed. For example:

  • A script doesn’t need w permission if it’s not edited.
  • A user doesn’t need w access to system binaries.

2. Audit Permissions Regularly

  • Use ls -la to check hidden files (e.g., ~/.bash_history, ~/.ssh).
  • Use find to locate risky permissions:
    # SUID binaries (potential privilege escalation)
    sudo find / -perm -4000 -ls 2>/dev/null
    
    # World-writable directories
    sudo find / -type d -perm -o+w -ls 2>/dev/null

3. Avoid SUID on Risky Binaries

Never set SUID on scripts (e.g., bash, python) or user-writable files—attackers can exploit them to gain root access.

4. Secure Sensitive Files

  • SSH keys: chmod 600 ~/.ssh/id_rsa (owner-only read/write).
  • Config files with passwords: chmod 600 /etc/mysql/my.cnf.

5. Use umask to Limit Defaults

Set umask 077 for users handling sensitive data to prevent accidental exposure.

6. Advanced: SELinux/AppArmor

For enterprise environments, use Mandatory Access Control (MAC) systems like SELinux (Red Hat) or AppArmor (Debian/Ubuntu) to enforce granular policies beyond standard permissions.

Conclusion

Linux permissions are a cornerstone of system security, governing access to files, directories, and critical binaries. By mastering chmod, chown, and special permissions like SUID/SGID, you can prevent unauthorized access, secure sensitive data, and maintain a robust system.

Remember: Regularly audit permissions, follow the principle of least privilege, and avoid overly permissive settings like world-writable files. With these practices, you’ll significantly reduce your attack surface and keep your Linux system secure.

References