Many sysadmins face this common scenario: You've run chmod -R go+r
on your Apache log directory, but non-root users still can't access the files. Let's break down why this happens and how to properly solve it.
The key insight is that Linux permissions require both file permissions and directory traversal permissions. Here's what actually happens when a user tries to access /var/log/httpd/oursite.com/error.log
:
1. Needs execute (x) permission on /var
2. Needs execute (x) permission on /var/log
3. Needs execute (x) permission on /var/log/httpd
4. Needs execute (x) permission on /var/log/httpd/oursite.com
5. Finally needs read (r) permission on the log file itself
Here's the complete command sequence to fix this:
# Set directory execute permissions
sudo find /var/log/httpd -type d -exec chmod go+rx {} \;
# Set file read permissions
sudo find /var/log/httpd -type f -exec chmod go+r {} \;
# Verify the changes
ls -la /var/log/httpd
ls -la /var/log/httpd/oursite.com/
For production systems, consider these more secure alternatives:
# Option 1: Add users to apache group
sudo usermod -a -G apache developer1
sudo usermod -a -G apache developer2
# Then set group permissions
sudo chown -R root:apache /var/log/httpd
sudo chmod -R g+r /var/log/httpd
sudo find /var/log/httpd -type d -exec chmod g+rx {} \;
Or using ACLs for finer control:
# Install ACL support if needed
sudo yum install acl # For CentOS/RHEL
sudo apt-get install acl # For Ubuntu/Debian
# Set ACL permissions
sudo setfacl -R -m g:developers:r /var/log/httpd
sudo setfacl -d -R -m g:developers:r /var/log/httpd
To ensure permissions survive log rotation, add this to your Apache config:
<IfModule log_config_module>
LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog "|/usr/sbin/rotatelogs /var/log/httpd/access_log 86400" common
ErrorLog "|/usr/sbin/rotatelogs /var/log/httpd/error_log 86400"
# Add these lines for permission persistence
umask 0022
create 0644 root apache
</IfModule>
If permissions still don't work:
# Check SELinux context
ls -Z /var/log/httpd
# If needed, set proper SELinux context
sudo chcon -R -t httpd_log_t /var/log/httpd
# Or temporarily check if SELinux is the issue
sudo setenforce 0
# Test your access
sudo setenforce 1
Remember to always test with actual user accounts rather than just checking permissions visually.
When managing Apache web servers, developers often need to access log files located in /var/log/httpd/
without root privileges. A common but misleading approach is to simply run:
chmod -R go+r /var/log/httpd
This command adds read permissions for group and others, but as shown in the example, users still get "Permission denied" errors when trying to access logs in subdirectories like /var/log/httpd/oursite.com/
.
The key insight is that Linux requires execute (x) permission on directories to access their contents. The current permissions:
drwxr--r-- 13 root root 4096 Oct 25 03:31 .
drwxr-xr-x. 6 root root 4096 Oct 20 03:24 ..
drwxr-xr-x 2 root root 4096 Oct 20 03:24 oursite.com
drwxr-xr-x 2 root root 4096 Oct 20 03:24 oursite2.com
Show that while files have read permissions (r--), the parent directory only gives execute (x) to owner and group, not others.
To properly grant access, we need to:
- Add execute permission for directories
- Maintain read permission for files
- Consider security implications
Here's the correct command sequence:
# Add execute on directories (d) for others
find /var/log/httpd -type d -exec chmod o+x {} \;
# Add read on files (f) for others
find /var/log/httpd -type f -exec chmod o+r {} \;
Instead of opening permissions globally, consider creating a dedicated group:
# Create logreader group
groupadd logreaders
# Add developers to the group
usermod -a -G logreaders developer1
usermod -a -G logreaders developer2
# Change group ownership of log files
chgrp -R logreaders /var/log/httpd/
# Set permissions (g=group, r=read, x=execute)
find /var/log/httpd -type d -exec chmod g+rx {} \;
find /var/log/httpd -type f -exec chmod g+r {} \;
# Set the setgid bit to maintain group ownership
chmod g+s /var/log/httpd/
After implementing either solution, test with:
sudo -u nobody tail /var/log/httpd/oursite.com/error.log
This simulates access as a non-privileged user. You should now be able to read logs without permission errors.