Quyền Unix trông như một bộ mã phải học thuộc: 755, 644, 600, 777. Thật ra không phải vậy. Mọi chế độ quyền đều được dựng từ ba con số (4, 2 và 1) cộng lại ba lần, và khi đã thấy điều đó, bạn đọc được mọi chế độ, viết được đúng chế độ mình cần và đoán trước umask sẽ làm gì. Bài này tính từng bước với ví dụ thật, giải thích phần hay gây bất ngờ (thư mục), và liệt kê những lỗi gây ra phần lớn rắc rối về quyền. Mọi kết quả đều kiểm tra được bằng công cụ tính quyền chmod.
Ba nhóm, mỗi nhóm ba bit
Mỗi tệp có một chủ sở hữu và một nhóm. Quyền được đặt cho ba lớp người dùng: chủ sở hữu (u), thành viên của nhóm (g), và mọi người khác (o). Mỗi lớp có ba công tắc:
| Công tắc | Chữ | Giá trị |
|---|---|---|
| đọc | r | 4 |
| ghi | w | 2 |
| thực thi | x | 1 |
Cộng giá trị các công tắc đang bật, bạn được một chữ số từ 0 đến 7. Ba chữ số, mỗi lớp một chữ số, tạo thành chế độ quyền.
Ví dụ: 754. Chủ 7 = 4+2+1 = rwx. Nhóm 5 = 4+1 = r-x. Người khác 4 = r--. Trong ls -l đó là -rwxr-xr--.
Chiều ngược lại: `rw-r-----`. Chủ rw- = 4+2 = 6, nhóm r-- = 4, người khác --- = 0, vậy chế độ là 640. Đây là chế độ hợp lý cho tệp cấu hình có mật khẩu, nhóm của dịch vụ đọc được còn những người khác thì không.
Các chế độ hay gặp nhất suy ra ngay:
- 755 (rwxr-xr-x): chương trình, script và thư mục mà ai cũng được dùng.
- 644 (rw-r--r--): tệp thông thường: tài liệu, ảnh, trang web.
- 600 (rw-------): tệp riêng tư. SSH từ chối dùng khóa bí mật mà người khác đọc được.
- 700 (rwx------): thư mục riêng, như
~/.ssh.
Vì sao dùng hệ bát phân? Vì ba bit vừa đúng một chữ số bát phân, nên các con số này không bao giờ có chữ số 8 hay 9.
Chữ số thứ tư: bit đặc biệt
Chế độ quyền có thể có thêm chữ số thứ tư ở đầu, cũng dựng theo cách đó: setuid là 4, setgid là 2, sticky là 1.
- 4755: setuid. Chương trình chạy với quyền của chủ sở hữu thay vì của người gọi.
passwdlà setuid root để người dùng thường đổi được mật khẩu của chính mình. - 2775 trên thư mục: setgid. Tệp mới tạo bên trong mang nhóm của thư mục thay vì nhóm chính của người tạo, nên thư mục chung của nhóm vẫn thuộc về cả nhóm.
- 1777: sticky.
/tmpai cũng ghi được, nhưng bit sticky khiến chỉ chủ của tệp mới xóa hay đổi tên được nó.
ls -l hiển thị các bit này ở vị trí thực thi: s (setuid hay setgid) và t (sticky) khi bit thực thi cũng bật, còn S hay T viết hoa khi không. Chữ hoa trên một tệp thường có nghĩa ai đó đã bật bit đặc biệt mà quên quyền thực thi.
Thư mục thì khác
Cùng ba chữ cái nhưng nghĩa khác với thư mục, và đây là nguồn gốc của nhiều thắc mắc "permission denied":
- r cho phép liệt kê tên trong thư mục.
- x cho phép đi vào và mở thứ bên trong theo tên.
- w cho phép tạo, đổi tên và xóa mục, và chỉ có tác dụng khi đi kèm x.
Vì thế thư mục r-- cho thấy tên tệp nhưng không mở được tệp nào; thư mục --x cho mở report.pdf nếu bạn biết tên, dù không liệt kê được. Còn xóa một tệp là thao tác trên thư mục: bạn xóa được tệp chỉ-đọc trong thư mục mình ghi được, và không xóa được tệp ghi được trong thư mục mình không ghi được.
umask: phép trừ, không phải chế độ quyền
Khi chương trình tạo tệp, nó xin 666 (rw cho mọi người); với thư mục nó xin 777. umask liệt kê các bit cần lấy đi. Chính xác thì đó là phép "và phủ định" theo bit, nhưng với các giá trị thông dụng, trừ từng chữ số cũng cho cùng kết quả:
| umask | tệp mới | thư mục mới |
|---|---|---|
| 022 | 666 − 022 = 644 | 777 − 022 = 755 |
| 027 | 640 | 750 |
| 077 | 600 | 700 |
| 002 | 664 | 775 |
Phép trừ sai khi umask lấy đi một bit vốn không có: umask 033 trên tệp cho 644, không phải 633, vì 666 không có bit thực thi để lấy đi. Công cụ tính theo đúng phép toán bit. Bảng cũng cho thấy vì sao script mới tạo không bao giờ chạy được ngay: tệp bắt đầu từ 666, không có x nào, nên bạn cần chmod +x.
chmod dạng ký hiệu
Thay vì số, bạn có thể nói cần đổi gì: chmod u+x,go-w file thêm thực thi cho chủ và bỏ ghi của nhóm và người khác, giữ nguyên phần còn lại. Bắt đầu từ 644 (rw-r--r--), kết quả là 744 (rwxr--r--). Một số dạng hữu ích:
chmod -R a+rX dircho cả cây thư mục đọc được. Chữ X hoa chỉ thêm thực thi cho thư mục và tệp vốn đã chạy được, nên tài liệu không biến thành chương trình.chmod g=u filechép quyền của chủ sang nhóm.chmod o= filebỏ mọi quyền của người khác.
Một chi tiết tinh tế: khi không ghi u, g, o hay a, chmod tôn trọng umask. Với umask 022, chmod +w file chỉ thêm quyền ghi cho chủ, còn chmod a+w file thêm cho tất cả.
Những lỗi hay gặp
- Dùng 777 để sửa lỗi quyền. Nó chạy được vì cho phép mọi thứ, kể cả bất kỳ tiến trình nào trên máy chủ web ghi đè mã của bạn. Cách sửa thật thường là quyền sở hữu:
chown www-data:www-datahoặc thêm người dùng vào đúng nhóm. - `chmod -R 755` cho cả cây. Mọi tệp đều thành chạy được. Hãy dùng
a+rXhoặc đặt riêng cho tệp và thư mục bằngfind -type fvàfind -type d. - Quên thư mục. Tệp 644 nằm trong thư mục 700 vẫn không ai khác đọc được.
- Số 0 đứng đầu trong tệp cấu hình. Trong YAML 1.1,
mode: 0644là số bát phân (420 hệ thập phân), trong YAML 1.2 lại là số thập phân 644. Hãy đặt giá trị trong nháy hoặc viết theo đúng tài liệu của công cụ. - Khóa bí mật để 644. SSH từ chối khóa mà người khác đọc được; hãy dùng 600.
Thử ngay
Đánh dấu ô hoặc gõ một chế độ trong công cụ tính quyền chmod, chuyển sang thẻ umask để xem mặc định của bạn tạo ra gì, và thử biểu thức ở thẻ "Áp dụng chmod" trước khi chạy trên máy chủ. Để tính toán hệ bát phân nói chung, công cụ đổi hệ cơ số hiển thị mọi số ở cơ số 8.