File permissions and access control are fundamental to Linux security. Understanding how to properly configure permissions, extend them with Access Control Lists (ACLs), and leverage mandatory access control systems like SELinux and AppArmor is essential for maintaining secure, well-organized systems. This guide provides comprehensive coverage of Linux access control mechanisms from basic permissions to advanced security frameworks.
Understanding Traditional Unix Permissions
Permission Model Basics
Linux implements a simple yet effective permission model with three permission types and three user categories.
Permission types:
- Read (r): View file contents or list directory contents
- Write (w): Modify file contents or create/delete files in directory
- Execute (x): Run file as program or enter directory
User categories:
- User (u): File owner
- Group (g): File’s group
- Others (o): Everyone else
Viewing Permissions
Use ls -l to view permissions:
ls -l /etc/passwd
-rw-r--r-- 1 root root 2847 Nov 10 10:00 /etc/passwd
Breaking down the permission string -rw-r--r--:
- First character: File type (
-= regular file,d= directory,l= symlink) - Next three: Owner permissions (rw-)
- Next three: Group permissions (r–)
- Last three: Other permissions (r–)
Numeric representation:
Permissions can be represented as octal numbers:
- Read = 4
- Write = 2
- Execute = 1
So rw-r--r-- = 644:
- Owner: 4+2+0 = 6 (rw-)
- Group: 4+0+0 = 4 (r–)
- Others: 4+0+0 = 4 (r–)
Changing Permissions with chmod
Symbolic mode:
# Add execute permission for user
chmod u+x file.sh
## Remove write permission for group
chmod g-w document.txt
## Set specific permissions for others
chmod o=r file.txt
## Multiple changes
chmod u+x,g-w,o-rwx script.sh
## Add read permission for all
chmod a+r file.txt
Numeric mode:
## Set permissions to rw-r--r--
chmod 644 file.txt
## Set permissions to rwxr-xr-x
chmod 755 script.sh
## Set permissions to rw-------
chmod 600 private.key
## Set permissions to rwxrwxrwx
chmod 777 file.txt # Generally not recommended!
Recursive changes:
## Change permissions recursively
chmod -R 755 /var/www/html
## Change only directories
find /var/www -type d -exec chmod 755 {} \;
## Change only files
find /var/www -type f -exec chmod 644 {} \;
Changing Ownership
Change owner:
## Change owner
sudo chown newuser file.txt
## Change owner and group
sudo chown newuser:newgroup file.txt
## Change only group
sudo chown :newgroup file.txt
## or
sudo chgrp newgroup file.txt
## Recursive ownership change
sudo chown -R www-data:www-data /var/www/html
Special Permissions
Setuid (SUID) - 4000:
When set on executable files, runs with owner’s privileges instead of executor’s.
## Set SUID
chmod u+s /usr/bin/passwd
## or
chmod 4755 /usr/bin/passwd
## View SUID files
find / -perm -4000 -type f 2>/dev/null
Example: /usr/bin/passwd has SUID so users can change their passwords (modifying /etc/shadow, which only root can write).
Setgid (SGID) - 2000:
On files: Runs with group’s privileges. On directories: New files inherit directory’s group.
## Set SGID on directory
chmod g+s /shared/directory
## or
chmod 2775 /shared/directory
Sticky Bit - 1000:
On directories: Only owner can delete their files (useful for /tmp).
## Set sticky bit
chmod +t /tmp/shared
## or
chmod 1777 /tmp/shared
## View sticky bit directories
ls -ld /tmp
drwxrwxrwt 20 root root 4096 Nov 11 10:00 /tmp
Default Permissions with umask
umask sets default permissions for newly created files and directories.
View current umask:
umask
## Output: 0022
How umask works:
- Default file permissions: 666 (rw-rw-rw-)
- Default directory permissions: 777 (rwxrwxrwx)
- umask subtracts from these defaults
With umask 022:
- Files: 666 - 022 = 644 (rw-r–r–)
- Directories: 777 - 022 = 755 (rwxr-xr-x)
Set umask:
## Temporary (current session)
umask 027
## Permanent (add to ~/.bashrc or /etc/profile)
echo "umask 027" >> ~/.bashrc
Common umask values:
022: Default, group/others can read but not write027: Group can read, others have no access077: Only owner has any access
Access Control Lists (ACLs)
ACLs extend traditional Unix permissions, allowing fine-grained per-user and per-group access control.
Why Use ACLs?
Traditional permissions limit you to one owner, one group, and everyone else. ACLs allow:
- Multiple users with different permissions
- Multiple groups with different permissions
- Default permissions for new files in directories
Viewing ACLs
## View ACLs
getfacl file.txt
## Output:
## file: file.txt
## owner: user1
## group: group1
## user::rw-
## group::r--
## other::r--
Setting ACLs
Grant user permissions:
## Give user2 read/write access
setfacl -m u:user2:rw file.txt
## Give user3 read-only access
setfacl -m u:user3:r file.txt
Grant group permissions:
## Give developers group read/write access
setfacl -m g:developers:rw file.txt
Multiple ACL entries:
setfacl -m u:alice:rwx,u:bob:rx,g:staff:r file.txt
Recursive ACLs:
## Apply ACLs recursively
setfacl -R -m u:user2:rw /path/to/directory
Default ACLs (for directories):
Default ACLs are inherited by new files created in the directory.
## Set default ACL
setfacl -d -m u:user2:rw /shared/directory
## New files in /shared/directory will give user2 rw access
Remove ACLs:
## Remove specific ACL entry
setfacl -x u:user2 file.txt
## Remove all ACLs
setfacl -b file.txt
ACL Mask
The ACL mask defines maximum permissions for named users, group owner, and named groups.
## Set mask
setfacl -m m::rx file.txt
## Even if user2 has rwx, mask limits to rx
Practical ACL Examples
Shared project directory:
## Create directory
mkdir /projects/webapp
sudo chown :developers /projects/webapp
## Set base permissions
chmod 770 /projects/webapp
## Give manager read-only access
setfacl -m u:manager:rx /projects/webapp
## Set default ACLs for new files
setfacl -d -m g:developers:rwx /projects/webapp
setfacl -d -m u:manager:rx /projects/webapp
Web server content with multiple maintainers:
## Give multiple users write access
setfacl -R -m u:alice:rwx,u:bob:rwx /var/www/html
setfacl -R -d -m u:alice:rwx,u:bob:rwx /var/www/html
## Maintain web server group access
setfacl -R -m g:www-data:rx /var/www/html
Backing Up and Restoring ACLs
## Backup ACLs
getfacl -R /path > acls-backup.txt
## Restore ACLs
setfacl --restore=acls-backup.txt
SELinux: Security-Enhanced Linux
SELinux implements Mandatory Access Control (MAC), adding an additional security layer beyond traditional permissions.
SELinux Concepts
SELinux provides:
- Process isolation
- Least privilege access
- Protection against zero-day exploits
- Role-based access control
SELinux modes:
- Enforcing: SELinux policy is enforced
- Permissive: Violations logged but not blocked
- Disabled: SELinux is turned off
SELinux context:
Every file, process, and port has a security context:
user:role:type:level
Example: system_u:object_r:httpd_sys_content_t:s0
- user: SELinux user
- role: SELinux role
- type: Most important, determines access
- level: MLS/MCS level
Checking SELinux Status
## Check SELinux status
sestatus
## Check current mode
getenforce
## View security contexts
ls -Z /var/www/html
ps -eZ | grep httpd
Changing SELinux Modes
Temporary change:
## Set to permissive
sudo setenforce 0
## Set to enforcing
sudo setenforce 1
Permanent change:
Edit /etc/selinux/config:
SELINUX=enforcing
SELINUXTYPE=targeted
Options:
SELINUX=enforcing: Enforce SELinux policySELINUX=permissive: Log violations onlySELINUX=disabled: Turn off SELinux
Reboot required for changes to take effect.
Managing SELinux Contexts
View file contexts:
ls -Z /var/www/html/index.html
Change file context:
## Change type
sudo chcon -t httpd_sys_content_t /var/www/html/file.html
## Change complete context
sudo chcon -u system_u -r object_r -t httpd_sys_content_t file.html
## Recursive change
sudo chcon -R -t httpd_sys_content_t /var/www/html
Restore default contexts:
## Restore file to default context
sudo restorecon /var/www/html/file.html
## Recursive restore
sudo restorecon -R /var/www/html
## Restore with verbose output
sudo restorecon -Rv /var/www/html
SELinux Booleans
Booleans enable/disable specific SELinux features.
## List booleans
getsebool -a
## Check specific boolean
getsebool httpd_can_network_connect
## Set boolean temporarily
sudo setsebool httpd_can_network_connect on
## Set boolean permanently
sudo setsebool -P httpd_can_network_connect on
Common booleans:
httpd_can_network_connect: Allow httpd to connect to networkhttpd_enable_homedirs: Allow httpd to access home directoriesftpd_anon_write: Allow anonymous FTP uploads
Managing SELinux Policies
View policies:
## List policy modules
semodule -l
## View policy details
seinfo
sesearch --allow -s httpd_t -t httpd_sys_content_t
Troubleshooting SELinux:
## View denials
sudo ausearch -m avc -ts recent
## Generate policy from denials
sudo audit2allow -a
## Create and install custom policy
sudo audit2allow -a -M mypolicy
sudo semodule -i mypolicy.pp
Practical SELinux Examples
Allow web server to serve files:
## Set correct context
sudo semanage fcontext -a -t httpd_sys_content_t "/web/html(/.*)?"
sudo restorecon -Rv /web/html
Allow application to bind to non-standard port:
## Allow httpd to bind to port 8080
sudo semanage port -a -t http_port_t -p tcp 8080
Troubleshoot SELinux denials:
## Check for denials
sudo ausearch -m AVC -ts recent
## View human-readable explanations
sudo sealert -a /var/log/audit/audit.log
AppArmor: Application Armor
AppArmor is an alternative MAC system, primarily used in Ubuntu and SUSE.
AppArmor vs SELinux
AppArmor:
- Simpler to use
- Path-based access control
- Easier profile creation
- Default on Ubuntu/Debian
SELinux:
- More comprehensive
- Label-based access control
- Finer-grained control
- Default on RHEL/Fedora/CentOS
AppArmor Modes
Enforce mode: Policy violations are blocked Complain mode: Violations logged but allowed
Checking AppArmor Status
## Check status
sudo aa-status
## View loaded profiles
sudo apparmor_status
Managing AppArmor Profiles
Profile locations:
/etc/apparmor.d/: Profile definitions/etc/apparmor.d/disable/: Disabled profiles
Enable profile:
## Enforce mode
sudo aa-enforce /etc/apparmor.d/usr.bin.firefox
## Complain mode
sudo aa-complain /etc/apparmor.d/usr.bin.firefox
Disable profile:
sudo ln -s /etc/apparmor.d/usr.bin.firefox /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/usr.bin.firefox
Reload profiles:
sudo systemctl reload apparmor
Creating AppArmor Profiles
Generate profile:
## Generate profile interactively
sudo aa-genprof /usr/bin/myapp
## Run application, exercise all functions
## aa-genprof monitors and builds profile
## Finalize profile
Manually create profile:
Example profile /etc/apparmor.d/usr.bin.myapp:
#include <tunables/global>
/usr/bin/myapp {
#include <abstractions/base>
#include <abstractions/nameservice>
# Allow reading configuration
/etc/myapp/** r,
# Allow reading and writing data
/var/lib/myapp/** rw,
# Allow network access
network inet stream,
# Allow executing helper programs
/usr/bin/helper rix,
# Deny everything else by default
}
Load profile:
sudo apparmor_parser -r /etc/apparmor.d/usr.bin.myapp
Troubleshooting AppArmor
View denials:
sudo dmesg | grep apparmor
sudo journalctl | grep apparmor
Audit log:
sudo aa-logprof
This tool helps update profiles based on denied actions.
Practical AppArmor Examples
Confine web browser:
## Put Firefox in complain mode
sudo aa-complain firefox
## Run Firefox, observe behavior
## Use aa-logprof to update profile
## Switch to enforce mode
sudo aa-enforce firefox
Restrict custom application:
## Create basic profile
sudo aa-autodep myapp
## Fine-tune with genprof
sudo aa-genprof /usr/local/bin/myapp
## Enforce the profile
sudo aa-enforce /usr/local/bin/myapp
Best Practices
Permission Best Practices
- Principle of least privilege: Grant minimum necessary permissions
- Regular audits: Periodically review file permissions
- Avoid 777: Never use unless absolutely necessary
- Secure sensitive files: 600 for private keys, passwords
- Proper directory permissions: 755 for most, 750 for restricted
- Web server content: 644 for files, 755 for directories
- Use groups effectively: Organize users into groups for easier management
ACL Best Practices
- Document ACLs: Keep records of ACL configurations
- Use default ACLs: Set defaults for shared directories
- Backup ACLs: Include in backup procedures
- Avoid ACL sprawl: Don’t overcomplicate with too many ACL entries
- Monitor ACL changes: Track modifications to sensitive files
SELinux/AppArmor Best Practices
- Don’t disable: Keep enforcing mode enabled
- Fix issues properly: Don’t blindly accept policy changes
- Use audit2allow carefully: Review suggested changes
- Test in permissive: Test policy changes before enforcing
- Keep updated: Update policies with system updates
- Document exceptions: Record any custom policies or booleans
- Regular audits: Review logs for violations
Security Checklists
File Permission Security Checklist
## Find world-writable files
find / -type f -perm -002 2>/dev/null
## Find files with no owner
find / -nouser -o -nogroup 2>/dev/null
## Find SUID/SGID files
find / -perm -4000 -o -perm -2000 2>/dev/null
## Check sensitive files
ls -l /etc/passwd /etc/shadow /etc/sudoers
## [Secure SSH](https://terabyte.systems/posts/how-to-secure-ssh-access-linux-servers/) keys
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 700 ~/.ssh
## Secure web server files
find /var/www -type f -exec chmod 644 {} \;
find /var/www -type d -exec chmod 755 {} \;
MAC System Security Checklist
## Verify SELinux/AppArmor is running
sestatus # or aa-status
## Check for violations
ausearch -m AVC -ts today # SELinux
dmesg | grep apparmor # AppArmor
## Verify critical services are confined
ps -eZ | grep httpd # SELinux
aa-status # AppArmor
## Review custom policies
semodule -l # SELinux
ls /etc/apparmor.d/ # AppArmor
Related Articles
- Advanced systemd Service Management and Unit File Creation
- Mastering Linux Package Management
- Understanding Linux Boot Process from BIOS to Init
- Quick Guide to Linux Process Management and Job Control
Conclusion
Linux provides multiple layers of access control, from traditional Unix permissions to advanced MAC systems. Understanding how to properly configure permissions, leverage ACLs for fine-grained control, and utilize SELinux or AppArmor for mandatory access control is essential for maintaining secure systems.
Traditional permissions form the foundation, ACLs extend flexibility for complex sharing scenarios, and MAC systems provide defense-in-depth protection against compromised applications. Used together, these mechanisms create robust, secure Linux environments resistant to unauthorized access and privilege escalation attacks.
Security is not a one-time configuration but an ongoing process. Regular audits, appropriate permission settings, and proper use of MAC systems significantly reduce security risks and protect valuable data and resources.
References
- Linux File Permissions: https://www.kernel.org/doc/html/latest/filesystems/
- ACL Documentation: https://man7.org/linux/man-pages/man5/acl.5.html
- SELinux User’s Guide: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/using_selinux/
- AppArmor Documentation: https://gitlab.com/apparmor/apparmor/-/wikis/Documentation