drwxr-xr-x là gì? Giải thích permission Linux
Đọc drwxr-xr-x từng ký tự để hiểu mode 755, quyền x trên thư mục là đi qua, và vì sao chmod 777 không phải cách sửa permission đúng.
Ý nghĩa của drwxr-xr-x
drwxr-xr-x mô tả một thư mục mà owner có thể thay đổi nội dung, còn mọi user khác có thể đọc và đi qua thư mục đó nhưng không thể thay đổi gì. Ở dạng octal, mode này là 755. Linux in 10 ký tự này ở đầu mỗi dòng output của ls -l. Chúng luôn có cùng ý nghĩa và cùng thứ tự, nên chỉ cần hiểu một chuỗi là bạn có thể hiểu tất cả chuỗi tương tự.
Có một quy tắc cần biết trước, vì nó quyết định việc tự kiểm tra của bạn có cho kết quả đúng hay không. User root bỏ qua các permission bit. Kernel cấp cho root capability CAP_DAC_OVERRIDE (discretionary access control override), nên root có thể mở các file có mode không cho phép việc đó. Mọi ví dụ trên trang này đều thành công khi chạy bằng root, bất kể các bit ghi gì. Hãy đăng nhập bằng user thông thường khi muốn quan sát các quy tắc này hoạt động.
Mười ký tự, đọc từng ký tự
Tạo một thư mục và một file để kiểm tra. Không có lệnh nào ở đây tác động ra ngoài thư mục mới.
mkdir -p ~/permdemo/inner
printf 'hello\n' > ~/permdemo/inner/notes.txt
ls -ld ~/permdemo ~/permdemo/inner ~/permdemo/inner/notes.txtVới umask mặc định phổ biến là 022, hai dòng thư mục bắt đầu bằng drwxr-xr-x và dòng file bắt đầu bằng -rw-r--r--.
Ký tự 1 cho biết loại file, không phải permission. d là thư mục. - là file thông thường. l là symbolic link. c và b lần lượt là device node dạng character và block. s là socket, còn p là named pipe. Ký tự này nằm ngoài giá trị octal, nên drwxr-xr-x trở thành 755 thay vì bắt đầu bằng d.
Chín ký tự phía sau được chia thành ba nhóm, mỗi nhóm ba ký tự, và thứ tự của chúng không bao giờ thay đổi.
- Ký tự 2 đến 4 là bộ ba owner, gồm các bit áp dụng cho user sở hữu file.
- Ký tự 5 đến 7 là bộ ba group, gồm các bit áp dụng cho group của file.
- Ký tự 8 đến 10 là bộ ba other, gồm các bit áp dụng cho tất cả user khác.
Trong một bộ ba, các vị trí luôn là r, sau đó w, rồi x; dấu gạch ngang nghĩa là bit đó đang tắt. Các chữ cái không đổi vị trí. r-x nghĩa là có quyền đọc nhưng không có quyền ghi. -w- nghĩa là có quyền ghi nhưng không có quyền đọc; trường hợp này hợp lệ nhưng hiếm gặp.
Vì vậy drwxr-xr-x được tách như sau: d cho thư mục, tiếp theo rwx cho owner, r-x cho group và r-x cho other.
Một số hệ thống in thêm ký tự thứ 11. Dấu chấm ở cuối, drwxr-xr-x., nghĩa là file có SELinux (security enhanced Linux) context. Các bản phân phối dùng SELinux như Fedora và Rocky mặc định in ký tự này. Dấu cộng ở cuối, drwxr-xr-x+, nghĩa là file có POSIX ACL (access control list), tức một tập rule bổ sung ngoài chín bit này. Dùng getfacl <path> để đọc các rule bổ sung đó.
r, w và x có tác dụng khác nhau trên thư mục
Đây là quy tắc đầu tiên mà người mới thường hiểu sai. Các chữ cái trên file và thư mục giống nhau. Nhưng quyền mà chúng cấp thì không giống nhau.
rtrên file cho phép đọc nội dung.rtrên thư mục liệt kê tên bên trong thư mục, đây là việc màlskhông có tùy chọn cần.wtrên file cho phép thay đổi nội dung.wtrên thư mục cho phép thêm và xóa entry trong thư mục. Xóa một file là thay đổi đối với thư mục, nên quyền write trên thư mục mới quyết định việc này; mode của chính file không có tác dụng.xtrên file cho phép chạy file như một chương trình.xtrên thư mục cho phép traverse, tức là kernel có thể resolve một tên bên trong thư mục trong quá trình tra cứu path.
Traverse là phần khiến nhiều người bất ngờ. x trên thư mục không chạy gì cả. Để mở /srv/site/index.html, cần x trên /, rồi x trên /srv, tiếp theo x trên /srv/site, và cuối cùng r trên file. Nếu một thư mục trong chuỗi đó không có x cấp cho bạn, quá trình tra cứu dừng tại đó, và caller nhận được Permission denied cho toàn bộ path, ngay cả khi file ở cuối có quyền đọc cho mọi người. namei -l /srv/site/index.html in từng bước trong chuỗi cùng mode và owner, để bạn thấy link nào làm quá trình bị dừng.
Một thư mục có r nhưng không có x là trạng thái nửa vời khá lạ mà bạn cần nhận biết. User thông thường có thể liệt kê tên, vì đó là quyền mà r cấp, nhưng không thể stat bất kỳ entry nào. Vì vậy ls -l điền dấu hỏi vào các cột size và mode, đồng thời in ls: cannot access ...: Permission denied cho từng entry.
Chuyển các ký tự thành 755
Mỗi bộ ba là một số ba bit. r có giá trị 4, w có giá trị 2, x có giá trị 1. Cộng các bit đang bật.
rwxlà 4 + 2 + 1 = 7rw-là 4 + 2 = 6r-xlà 4 + 1 = 5r--là 4---là 0
drwxr-xr-x vì vậy là 7 cho owner, 5 cho group và 5 cho other: 755. -rw-r--r-- là 6, 4, 4: 644. drwxrwxr-x là 7, 7, 5: 775, tức 755 với quyền ghi được thêm cho group. Bạn không cần tự đếm ký tự, vì stat in cả hai dạng cùng lúc.
stat -c '%A %a %U %G %n' ~/permdemo ~/permdemo/inner/notes.txt%A là dạng ký tự, %a là dạng bát phân, còn %U và %G cho biết user sở hữu và group sở hữu.
Các chuỗi quyền mà mọi người thường tìm kiếm
Đây là những mode thường gặp trên một server thực tế, kèm giá trị octal và vị trí thường xuất hiện.
-rw-r--r--là 644. File thông thường mà service chỉ đọc, chẳng hạn file cấu hình hoặc trang HTML.-rw-------là 600. Dữ liệu bí mật: private key SSH hoặc file.envcủa ứng dụng.-rw-rw-r--là 664. File trong một thư mục được chia sẻ cho một group, nơi các thành viên cần quyền ghi.-rwxr-xr-xlà 755. Script và binary, chẳng hạn/usr/local/bin/backup.shvà hầu hết/usr/bin.-rwx------là 700. Script riêng tư mà chỉ owner mới được chạy.drwxr-xr-xlà 755. Gần như mọi thư mục hệ thống và document root của website.drwx------là 700.~/.sshvà các thư mục home trên một máy được khóa chặt.drwxrwxr-xlà 775. Thư mục mà group của owner có thể ghi vào.drwxrwsr-xlà 2775. Tương tự, nhưng có thêm bit setgid, nên các file mới bên trong sẽ kế thừa group của thư mục.drwxrwxrwtlà 1777./tmp.tở cuối là sticky bit, nên user chỉ có thể xóa file của chính mình.-rwsr-xr-xlà 4755. Binary setuid chạy với quyền của owner, chẳng hạn/usr/bin/passwdvà/usr/bin/sudo.-rw-rw-rw-là 666, còndrwxrwxrwxlà 777. Cho phép mọi user ghi, và trên server điều này gần như luôn là một lỗi.lrwxrwxrwxlà chuỗi mà mọi symbolic link đều hiển thị. Linux bỏ qua các bit mode trên link và kiểm tra target thay vào đó, nên chuỗi này hoàn toàn không có ý nghĩa.
Triad nào áp dụng cho bạn
Đây là quy tắc thứ hai mà người mới thường hiểu sai. Kernel chỉ chọn đúng một triad rồi dừng lại.
Nếu user ID của bạn khớp với owner của file, bạn nhận triad owner. Các bit group và other không được kiểm tra. Nếu không, kernel kiểm tra group của file có nằm trong một group của bạn hay không. Nếu có, bạn nhận triad group. Nếu không, bạn nhận triad other.
Điều này dẫn đến hai điểm. Triad owner vẫn được áp dụng ngay cả khi đây là triad hạn chế nhất. File có mode 0466, hiển thị là -r--rw-rw-, chỉ cho owner quyền đọc nhưng cho mọi người khác quyền ghi, vì điều kiện owner khớp trước và kernel không kiểm tra các bit phía sau. Đây là hành vi hợp lệ và thường gây nhầm lẫn khi mới gặp lần đầu.
Triad group được chọn theo group của file, không phải theo danh sách các group mà bạn thuộc về. ls -l in hai tên trên mỗi dòng: owner trước, group sau. Chỉ group thứ hai đó mới có quyền quyết định trên file. Việc bạn thuộc hai mươi group chỉ có ích khi file mang một trong các group đó.
id
stat -c '%U %G %A %n' ~/permdemo/inner/notes.txtid in user của bạn và mọi group mà bạn thuộc về. stat in owner và group của file. So sánh hai kết quả này để biết kernel sẽ dùng triad nào cho bạn.
Đó là lý do một thư mục dùng chung thường được gán một group và bật bit setgid. sudo chmod 2775 /srv/shared hiển thị là drwxrwsr-x, sau đó các file được tạo bên trong sẽ kế thừa group của thư mục thay vì group cá nhân của người tạo, để người tiếp theo vẫn có thể ghi vào chúng. Việc cấp riêng một account cho từng service là phần còn lại của vấn đề này. Nội dung đó được trình bày trong mỗi service dùng một user Linux riêng trên VPS.
umask quyết định mode của mọi file mới
File mới không lấy mode từ bạn. Nó lấy mode từ chương trình tạo ra file, sau đó trừ các bit mà umask xóa. umask là mask dùng để xóa bit, vì vậy umask càng lớn thì file càng riêng tư.
Hầu hết distribution được cài sẵn giá trị 022. Chương trình tạo regular file sẽ yêu cầu 0666. Chương trình tạo directory sẽ yêu cầu 0777. umask xóa 022 khỏi cả hai yêu cầu này, nên file có mode 644 và directory có mode 755. Đây chính là cặp giá trị thường thấy trên một VPS mới.
umask
umask -S
touch ~/permdemo/new.txt && mkdir -p ~/permdemo/newdir
ls -ld ~/permdemo/new.txt ~/permdemo/newdirumask -S in cùng giá trị dưới dạng chữ, dễ đọc hơn 0022. Đặt umask 027 trong ~/.profile để có default chặt chẽ hơn: file dùng 640 và directory dùng 750, cho phép group của bạn đọc các file công việc, còn những người khác thì không có quyền truy cập.
Có hai giới hạn cần nhớ. umask chỉ có thể xóa bit, không thể thêm bit. Vì vậy, file mới tạo sẽ không bao giờ có quyền executable, bất kể bạn đặt umask thế nào. Ngoài ra, systemd service không đọc shell profile của bạn, nên hãy đặt giá trị này trong unit file.
[Service]
UMask=0027Vì sao file web dùng 644 và thư mục web dùng 755
Web server chạy bằng account riêng, www-data trên Debian và Ubuntu, nginx trên Rocky và Alma. Tiến trình đó cần quyền đọc trên các file được phục vụ và quyền traverse trên các thư mục nằm phía trên chúng. Nó không có lý do gì để ghi vào các file và thư mục này. Static site tuyệt đối không nên cho phép việc đó.
Quyền 644 trên file cho owner quyền ghi và mọi người quyền đọc, nên deploy user có thể publish còn web user có thể phục vụ file. Quyền 755 trên thư mục cho owner quyền ghi và mọi người quyền traverse, nên web user có thể đi qua đường dẫn nhưng không thể thêm hoặc xóa gì. Khi đó, bug trong application cũng không thể ghi đè các page mà nó đang phục vụ.
Quy tắc traverse thường gây lỗi ngay tại đây. Nếu site nằm trong /home/deploy/site và /home/deploy có quyền 750, web user hoàn toàn không thể đi vào home directory. Request sẽ kết thúc bằng HTTP 403, kèm một dòng như sau trong /var/log/nginx/error.log:
open() "/home/deploy/site/index.html" failed (13: Permission denied), client: 203.0.113.5Số 13 là EACCES, tức kernel từ chối quyền truy cập. Network không có vấn đề gì: port vẫn listening và request đã đến nơi. Điều này dễ gây nhầm lẫn khi bạn vẫn đang học cách port listening hoạt động trên Linux. Chạy namei -l /home/deploy/site/index.html rồi đọc dọc theo chuỗi để tìm thư mục đầu tiên không có x cho other.
Thư mục mà application cần ghi vào, chẳng hạn upload path, là ngoại lệ. Hãy cấp quyền bằng ownership thay vì dùng mode rộng hơn: sudo chown -R www-data:www-data /srv/site/uploads và giữ mode ở mức 755. Chỉ cấp quyền ghi cho đúng thư mục cần quyền đó.
chmod mà không làm phẳng toàn bộ cây thư mục
chmod có cả hai dạng. Dạng bát phân đặt cả 9 bit cùng lúc: chmod 644 notes.txt. Dạng symbolic chỉ thay đổi phần bạn chỉ định và giữ nguyên phần còn lại: chmod u+x deploy.sh thêm quyền execute cho owner, còn chmod go-w notes.txt xóa quyền write của group và other.
Đệ quy là chỗ dễ làm hỏng cây thư mục. chmod -R 755 . đánh dấu mọi file ảnh và mọi file cấu hình là executable, vì chmod không thể phân biệt script với JPEG. Hãy dùng chữ hoa X thay thế.
chmod -R u=rwX,go=rX ~/permdemo
stat -c '%a %n' ~/permdemo ~/permdemo/inner/notes.txtX chữ hoa áp dụng quyền execute cho directory và cho các file vốn đã có một execute bit ở đâu đó. Directory sẽ có quyền 755, file thông thường sẽ có quyền 644, còn các script vốn đã executable vẫn giữ nguyên trạng thái đó. Khi một file đã có mode mà bạn tin cậy, chmod --reference=good.sh other.sh sẽ sao chép mode đó sang các file khác.
Các thông báo xuất hiện khi một bit bị đặt sai
bash: ./deploy.sh: Permission denied nghĩa là script không có bit x trong triad áp dụng cho bạn, hoặc một thư mục trên đường dẫn của nó không có bit x. chmod u+x deploy.sh sửa được trường hợp đầu tiên.
bash: ./deploy.sh: cannot execute: required file not found là một lỗi khác có tên dễ gây nhầm lẫn. Bit x vẫn đúng, nhưng interpreter được chỉ định ở dòng đầu tiên không tồn tại. Nguyên nhân thường gặp là ký tự xuống dòng của Windows, khiến kernel tìm một interpreter có tên /bin/bash\r. Sửa bằng sed -i 's/\r$//' deploy.sh.
Permissions 0644 for '/home/deploy/.ssh/id_ed25519' are too open. xuất phát từ SSH client, vì client từ chối dùng private key mà các account khác có thể đọc. Key cần quyền 600 và ~/.ssh cần quyền 700. Hướng dẫn đầy đủ về quản lý key và quyền file của SSH có tại quản lý SSH key và quyền file của chúng.
Authentication refused: bad ownership or modes for directory /home/deploy/.ssh xuất hiện trong journal của server khi home directory hoặc .ssh của nó cho phép group ghi. Thiết lập StrictModes của sshd từ chối key, còn phía client chỉ hiển thị một prompt yêu cầu password bất ngờ mà không giải thích nguyên nhân.
sudo: /etc/sudoers is world writable, tiếp theo là sudo: no valid sudoers sources found, quitting, nghĩa là sudo đã kiểm tra mode của file cấu hình chính nó và từ chối chạy. File đó phải có quyền 0440. Đây là hậu quả điển hình của một lệnh chmod đệ quy trên phạm vi rộng. Lỗi này có thể xảy ra cùng với thông báo của sshd ở trên, khiến console của nhà cung cấp là cách duy nhất để truy cập lại server.
Vì sao 777 không phải cách sửa đúng
777 cấp quyền ghi cho mọi tài khoản trên máy và mọi tiến trình chạy dưới các tài khoản đó. Server chạy các service bằng user riêng, nên “mọi người” trên VPS bao gồm nhiều đối tượng hơn rất nhiều so với trên laptop. Nếu một service bị breach, nó có thể ghi vào mọi nơi mà 777 cho phép.
Trong web root, tác hại xảy ra trực tiếp. Một thư mục cho phép mọi tài khoản ghi và đồng thời được server phục vụ sẽ biến lỗ hổng upload file thành cách chèn một script rồi gọi lại script đó.
777 gần như luôn là câu trả lời sai cho vấn đề ownership. Triệu chứng là “app không thể ghi vào thư mục này”. Nguyên nhân là thư mục thuộc về sai user. sudo chown -R appuser:appuser /srv/app/storage với mode 755 giải quyết được vấn đề và ngăn mọi tài khoản khác truy cập ghi. Việc tạo các tài khoản đó trước khi triển khai bất kỳ thứ gì nằm trong 10 phút đầu tiên trên một VPS mới.
Quyền ghi cho mọi tài khoản hợp lệ tại một vị trí quen thuộc là /tmp, và được viết là drwxrwxrwt. t ở cuối là sticky bit: mọi tài khoản đều có thể ghi vào thư mục, nhưng mỗi user chỉ có thể xóa các file do chính mình sở hữu. Nếu không có bit này, bất kỳ tài khoản nào cũng có thể xóa file tạm của tài khoản khác.
Đọc mode trước khi thay đổi
Các lệnh này chỉ đọc trạng thái, nên an toàn khi chạy ở bất kỳ đâu.
id
umask
stat -c '%A %a %U %G %n' ~/permdemo ~/permdemo/inner/notes.txt
namei -l ~/permdemo/inner/notes.txt
find ~/permdemo -perm -0002find <path> -perm -0002 liệt kê mọi thứ bên dưới một đường dẫn có bật bit ghi cho mọi người. Đây là cách nhanh nhất để audit một máy chủ sau khi ai đó đã sửa chữa bằng chmod 777.
Để kiểm tra một service account cụ thể có thể truy cập vào một thư mục hay không, hãy thực hiện kiểm tra với account đó. sudo -u www-data test -x /srv/site && echo yes || echo no in yes khi user đó có quyền traverse trên thư mục và in no khi không có quyền này. Kiểm tra với root không chứng minh được điều gì, vì root bỏ qua bước kiểm tra nên kết quả luôn là yes.
FAQ
drwxr-xr-x trong Linux có nghĩa là gì?
Đây là một directory, được nhận biết qua ký tự đầu tiên d, với mode 755. Nhóm quyền của owner là rwx, nên owner có toàn bộ quyền trên directory này. Nhóm quyền của group là r-x và nhóm quyền của other là r-x, nên mọi account khác đều có thể liệt kê tên bên trong và traverse directory, nhưng chỉ owner mới có thể thêm hoặc xóa nội dung. Dùng stat -c '%A %a %U %G %n' <path> để kiểm tra một path; lệnh này in dạng ký tự và dạng octal cạnh nhau.
Vì sao web file có mode 644 và web directory có mode 755?
Web server chạy dưới một account khác, là www-data trên Ubuntu. Nó cần quyền read trên các file được serve và quyền traverse trên mọi directory nằm phía trên các file đó. Nó không cần quyền write trên cả hai loại này. Mode 644 cho owner quyền write và mọi account khác quyền read. Mode 755 cho owner quyền write và mọi account khác quyền traverse. Một directory mà application thực sự cần ghi dữ liệu nên được bàn giao bằng chown cho user của application đó, thay vì nới mode cho tất cả mọi người.
Bit x có nghĩa là tôi có thể execute một directory không?
Không. Với directory, x có nghĩa là traverse, tức quyền resolve một name bên trong directory khi kernel đi qua một path. cd cần quyền này, và mọi thao tác open file bên dưới directory đó cũng vậy. Mỗi directory trên path đều cần x, nên một file có mode 644 vẫn không thể truy cập nếu một directory phía trên thiếu x đối với bạn. namei -l /path/to/file in mode của mọi directory trong chuỗi, giúp xác định lookup dừng ở đâu.
chmod 777 có bao giờ là cách sửa đúng không?
Gần như không bao giờ trên server. Nó cấp quyền write cho mọi account trên máy, bao gồm các account mà service sử dụng để chạy. Vì vậy, một service bị breach có thể ghi đè file. Khi một application không thể ghi vào directory, vấn đề thực sự thường là ownership: sudo chown -R appuser:appuser /srv/app/storage với mode 755 cấp cho application những quyền cần thiết và không cho các account khác truy cập ghi. Ngoại lệ quen thuộc là /tmp với mode 1777. Trường hợp này chỉ an toàn vì sticky bit ngăn user xóa file của user khác.
Vì sao ls in một dấu chấm hoặc dấu cộng sau phần quyền?
Ký tự thứ 11 mô tả các rule nằm ngoài 9 bit quyền cơ bản. Dấu chấm, như trong drwxr-xr-x., cho biết một SELinux security context được gắn vào file hoặc directory. Đây là trạng thái bình thường trên Fedora và Rocky. Dấu cộng, như trong drwxr-xr-x+, cho biết một POSIX ACL (access control list) đã được thiết lập, nên một user hoặc group có các quyền không xuất hiện trong 3 nhóm quyền cơ bản. Chạy getfacl <path> để liệt kê các entry bổ sung đó.