Vấn đề
Bạn cài xong Nginx, mở trình duyệt và nhận được màn hình trắng với thông báo 403 Forbidden. Không có stack trace, không có thông báo nào hữu ích. Hầu như luôn xuất phát từ một trong hai nguyên nhân: Nginx không thể đọc file vì vấn đề quyền truy cập, hoặc nó đang tìm một file index không tồn tại.
Chín trên mười lần, điều này xảy ra ngay sau khi cài server mới, sau khi deploy file với quyền root, hoặc sau khi thay đổi document root trong config.
Gỡ lỗi trước: Đọc Error Log
Chưa cần thay đổi gì cả. Hãy kiểm tra Nginx đang báo lỗi gì:
sudo tail -f /var/log/nginx/error.log
Bạn sẽ thấy một trong hai dạng này:
# Trường hợp 1 — bị từ chối quyền đọc file
2024/01/15 10:23:45 [error] 1234#0: *1 open() "/var/www/html/index.html" failed (13: Permission denied)
# Trường hợp 2 — không tìm thấy file index trong thư mục
2024/01/15 10:23:45 [error] 1234#0: *1 directory index of "/var/www/html/" is forbidden
Nguyên nhân khác nhau, cách sửa khác nhau. Biết mình đang gặp loại nào giúp bạn không lãng phí thời gian đi sai hướng.
Cách sửa 1: Sai quyền file hoặc thư mục
Thông báo Permission denied có nghĩa là tiến trình worker của Nginx không thể đọc file. Worker chạy với một user cụ thể — www-data trên Debian/Ubuntu, nginx trên CentOS/RHEL.
Kiểm tra quyền hiện tại
ls -la /var/www/html/
Hai con số này bao phủ hầu hết mọi trường hợp:
- Thư mục:
755— phải có quyền execute (có thể duyệt qua) - File:
644— tất cả có thể đọc, chỉ chủ sở hữu mới được ghi
Sửa quyền đệ quy
# Sửa quyền cho tất cả thư mục
sudo find /var/www/html -type d -exec chmod 755 {} \;
# Sửa quyền cho tất cả file
sudo find /var/www/html -type f -exec chmod 644 {} \;
Sửa ownership
Dù quyền đúng, nhưng nếu file thuộc sở hữu của root mà Nginx chạy với user www-data, thì vẫn không truy cập được:
# Xác nhận user mà worker đang chạy với
ps aux | grep nginx | grep worker
# Sửa ownership (đổi www-data thành nginx trên CentOS/RHEL)
sudo chown -R www-data:www-data /var/www/html/
Đừng quên các thư mục cha — Nginx cần quyền execute trên mọi thư mục trong đường dẫn, không chỉ web root:
ls -la /var/
ls -la /var/www/
Cách sửa 2: Thiếu file index
Thấy thông báo directory index is forbidden? Nginx tìm thấy thư mục đó rồi — chỉ là không có file index nào phù hợp để phục vụ, và nó không hiển thị danh sách thư mục vì autoindex mặc định bị tắt.
Kiểm tra Nginx đang tìm file index nào
grep -r "index" /etc/nginx/sites-enabled/
# hoặc kiểm tra giá trị mặc định trong http block
grep "index" /etc/nginx/nginx.conf
Mặc định thường là index index.html index.htm hoặc index index.php index.html cho các stack PHP.
Kiểm tra file có tồn tại không
ls -la /var/www/html/
Nếu bạn chỉ có file home.html nhưng Nginx đang tìm index.html, hãy chọn một trong các cách sửa sau:
Tùy chọn A — Tạo hoặc đổi tên file index:
mv /var/www/html/home.html /var/www/html/index.html
Tùy chọn B — Cập nhật server block Nginx để bao gồm tên file thực tế của bạn:
server {
listen 80;
server_name example.com;
root /var/www/html;
index home.html index.html index.htm;
}
Cần hiển thị danh sách thư mục?
server {
location /files/ {
autoindex on;
}
}
Chỉ bật tính năng này cho các đường dẫn không nhạy cảm. Không bao giờ bật trên web root.
Cách sửa 3: SELinux chặn truy cập (CentOS/RHEL)
Trên các hệ thống dựa trên RHEL, SELinux có thể âm thầm chặn Nginx ngay cả khi quyền truy cập và ownership trông có vẻ đúng:
# Kiểm tra audit log để tìm các lần bị từ chối liên quan đến Nginx
sudo audit2why -a | grep nginx
# Khôi phục SELinux context đúng
sudo restorecon -Rv /var/www/html/
# Hoặc đặt thủ công
sudo chcon -Rt httpd_sys_content_t /var/www/html/
Kiểm tra lại sau khi sửa
# Kiểm tra config, sau đó reload không gây downtime
sudo nginx -t && sudo systemctl reload nginx
# Xác nhận phản hồi
curl -I http://localhost
# Mong đợi: HTTP/1.1 200 OK
# Kiểm tra error log đã sạch chưa
sudo tail -20 /var/log/nginx/error.log
Danh sách kiểm tra nhanh
- Error log ghi Permission denied → sửa
chmodvàchown - Error log ghi directory index is forbidden → thêm hoặc trỏ đến file index
- Thư mục là
755, file là644 - Chủ sở hữu khớp với user của Nginx worker (
www-datahoặcnginx) - Các thư mục cha cũng có thể duyệt qua
- SELinux context được đặt đúng trên RHEL/CentOS
Mẹo: Tính quyền mà không cần đoán mò
Nếu bạn cần giá trị nào khác ngoài 644 hoặc 755 và không chắc về giá trị octal, công cụ Unix Permissions Calculator trên ToolCraft rất tiện — chỉ cần tick các ô owner/group/other và nó hiện ngay con số. Hữu ích khi cài thư mục upload hoặc CGI script với yêu cầu quyền không chuẩn.
Bài học rút ra
Hầu hết lỗi 403 đều bắt nguồn từ hai thói quen: deploy file với quyền root mà không sửa ownership sau đó, và không kiểm tra xem tên file index có khớp với config Nginx không. Error log nói thẳng về điều này — nó chỉ đúng tên file và đúng lý do. Hãy bắt đầu từ đó, không phải từ thông báo trên trình duyệt, và bạn thường sẽ sửa được trong vòng chưa đến hai phút.

