After setting up Nginx on Arch Linux with a dedicated nginx
user, I encountered a frustrating 403 Forbidden error despite correct file ownership. Here's what the configuration looked like:
# /etc/nginx/nginx.conf
user nginx nginx;
# Virtual host configuration
server {
location / {
root /home/lamnk/sites/host.com;
index index.html;
}
}
The directory permissions showed:
$ ls -la /home/lamnk/sites/host.com
-rw-r--r-- 1 nginx nginx 21 Jan 12 index.html
The critical insight came when checking parent directory permissions using namei
:
$ namei -l /home/lamnk/sites/host.com
drwx------ lamnk users /home/lamnk
Nginx couldn't traverse the home directory because:
- The
/home/lamnk
directory had 700 permissions (drwx------) - Only the owner (
lamnk
) had execute (x) permission - Nginx worker processes running as
nginx
user couldn't access the path
Here are three reliable approaches to resolve this:
1. Change Home Directory Permissions (Simple)
chmod 711 /home/lamnk
chmod +x /home/lamnk/sites
2. Move Webroot Outside Home Directory (Recommended)
# Create standard web directory
sudo mkdir -p /srv/http/host.com
sudo chown nginx:nginx /srv/http/host.com
# Update Nginx config
root /srv/http/host.com;
3. ACL-based Solution (Advanced)
setfacl -m u:nginx:x /home/lamnk
setfacl -m u:nginx:rx /home/lamnk/sites
setfacl -R -m u:nginx:r /home/lamnk/sites/host.com
Use this command to test permissions as the nginx user:
sudo -u nginx stat /home/lamnk/sites/host.com/index.html
Check Nginx error logs for confirmation:
tail -f /var/log/nginx/error.log
When dealing with home directory access:
- Never use 777 permissions
- Consider creating a dedicated
/srv/http
structure - Regularly audit permissions with
namei -l
- Use ACLs for fine-grained control rather than opening up permissions
Recently while configuring Nginx on Arch Linux, I encountered a puzzling scenario where Nginx couldn't access files despite having matching user ownership. Here's the complete picture:
# Nginx config (/etc/nginx/nginx.conf)
user nginx nginx;
# Directory structure
$ ls -la /home/lamnk/sites/host.com
total 12
drwxr-xr-x 2 lamnk http 4096 Jan 12 09:37 .
drwxr-xr-x 3 lamnk users 4096 Jan 12 09:36 ..
-rw-r--r-- 1 nginx nginx 21 Jan 12 09:37 index.html
The error appeared in Nginx's error log:
2016/01/12 17:28:23 [error] 31914#0: *2 open() "/home/lamnk/sites/host.com/index.html"
failed (13: Permission denied), client: 171.233.242.40,
server: host.com, request: "GET /index.html HTTP/1.1", host: "host.com"
The paradox: Nginx runs as user nginx
, the file is owned by nginx
, yet access is denied.
Examining parent directories revealed the issue:
$ namei -l /home/lamnk/sites/host.com
f: /home/lamnk/sites/host.com
drwxr-xr-x root root /
drwxr-xr-x root root home
drwx------ lamnk users lamnk
drwxr-xr-x lamnk users sites
drwxr-xr-x lamnk http host.com
The critical finding: The home directory /home/lamnk
has permissions drwx------
(700), meaning only the owner (lamnk
) has access.
For Nginx to access a file, it needs:
- Execute permission on all parent directories
- Read permission on the file itself
Even though the target file is owned by nginx
, Nginx can't traverse the path because:
/home/lamnk - 700 (only lamnk can access)
/home/lamnk/sites - 755 (world-executable)
/home/lamnk/sites/host.com - 755 (world-executable)
Option 1: Change home directory permissions
chmod 755 /home/lamnk
This is generally not recommended for security reasons.
Option 2: Move webroot outside home directory
sudo mkdir -p /var/www/host.com
sudo chown -R nginx:nginx /var/www/host.com
Then update Nginx config:
location / {
root /var/www/host.com;
index index.html;
}
Option 3: Create a dedicated user group
sudo groupadd webdev
sudo usermod -aG webdev lamnk
sudo usermod -aG webdev nginx
chown -R lamnk:webdev /home/lamnk/sites
chmod -R 750 /home/lamnk/sites
The most maintainable solution is using standard web directories:
# Create proper web directory
sudo mkdir -p /srv/http/host.com
sudo chown -R nginx:nginx /srv/http/host.com
sudo chmod -R 755 /srv/http/host.com
# Alternative for multiple users
sudo mkdir -p /srv/http/host.com
sudo chown -R lamnk:nginx /srv/http/host.com
sudo chmod -R 775 /srv/http/host.com
This follows Linux Filesystem Hierarchy Standard while maintaining security.
Useful commands for diagnosis:
# Check effective permissions
sudo -u nginx ls -l /home/lamnk/sites/host.com
# Test actual access
sudo -u nginx cat /home/lamnk/sites/host.com/index.html
# Verify directory traversal
namei -l /path/to/file