Tuesday, July 30, 2013

Cấp quyền thực thi với sudo

Một trong những câu hỏi thường gặp nhất của người mới sử dụng Ubuntu là về sudo. Cơ chế bảo mật này được kích hoạt mặc định trong Ubuntu và mang lại nhiều ưu điểm hơn cơ chế chuyển sang người dùng khác bằng su truyền thống. Trong đó ưu điểm lớn nhất là cho phép nhà quản trị kiểm soát được các thao tác của người dùng có can thiệp đến hệ thống, giao quyền thực thi “đúng người đúng việc”. Ngoài ra khi thực thi lệnh từ xa thông qua telnet/SSH thì sudo thực sự thể hiện ưu thế. Vì vậy nắm vững cơ chế sudo sẽ giúp ích rất nhiều cho những ai đang sử dụng Ubuntu.

Sudo được dùng khi ta muốn thực thi một lệnh trên Linux với quyền của một user khác. Nếu được cho phép, ta sẽ thực thi một lệnh như là người quản trị hay một user nào khác. Các khai báo “ai được làm gì” đặc tả trong file “/etc/sudoers”. Những ghi nhận (log) của hệ thống khi sudo được sử dụng theo mặc định nằm trong file /var/log/secure (Red Hat/Fedora / CentOS Linux) hoặc /var/log/auth.log (Ubuntu / Debian Linux).
Nếu người triệu gọi sudo là root hoặc khi người triệu gọi và người được “mượn” quyền là một thì sẽ không có xác nhận mật khẩu. Còn ngoài ra, sudo yêu cầu người dùng phải tự xác nhận bằng mật khẩu. Lưu ý ở đây là trong cấu hình mặc định thì mật khẩu để xác nhận này là mật khẩu của người triệu gọi, chứ không phải mật khẩu của root. Khi người dùng đã được xác nhận xong, hệ thống sẽ thiết lập một khoảng thời gian cho phép người triệu gọi tiếp tục dùng sudo mà không cần phải xác nhận mật khẩu lại (mặc định là 15 phút).
Cách sử dụng thông dụng nhất của sudo là cú pháp
sudo <lệnh cần thực hiện>
Chẳng hạn “sudo rm -rf /etc/someconfig.cfg”.
Cũng giống như su, nếu không có khai báo định danh của user đích rõ ràng, mặc định sudo sẽ xem như ta đang mượn quyền root để thực thi. Nếu ta muốn “mượn” một người dùng nào khác thì khai báo định danh rõ ràng của người đó, chẳng hạn
sudo -u training rm -rf /home/training/.recently-used
Bây giờ ta sẽ xem làm cách nào để thiết lập cho sudo biết “ai được làm gì”.

Cú pháp của file /etc/sudoers

Như đã nói ở trên, đây là file chứa tất cả những thiết lập cho sudo. Nội dung trong file này thường được đặc tả bằng cú pháp sau:
USER HOSTNAME=(TARGET-USERS) COMMAND
Trong đó:
  • USER: Tên của người sử dụng
  • HOSTNAME: Tên máy mà luật được áp dụng lên. Tham số này cần thiết vì sudo được thiết kế để bạn có thể dùng một file sudoers cho các máy khác. Lúc này sudo sẽ xem máy đang chạy được dùng các luật nào. Nói cách khác, bạn có thể thiết kế các luật cho từng máy trong hệ thống.
  • TARGET-USERS: Tên người dùng đích cho “mượn” quyền thực thi.
  • COMMAND: Tên “lệnh” (thực ra là các chương trình thực thi) mà người dùng được quyền thực thi với bất kỳ tham số nào mà họ muốn. Tuy nhiên bạn cũng có thể đặc tả các tham số của lệnh (bao gồm các dấu thay thế wildcards). Ngược lại, có thể dùng kí hiệu “” để ám chỉ là lệnh chỉ được thực thi mà không có tham số nào cả.
  • Nếu là cấp quyền cho group, ta thay tham số USER bằng %GROUP
Xem thêm “man sudoers” để biết cú pháp chi tiết hơn.

Thiết lập cho sudo

Sau khi biết cú pháp của file sudoers, ta sẽ tiến hành thiết lập cho sudo bằng cách soạn thảo file này. Để mở file sudoer lên và soạn thảo, ta dùng lệnh sau:
# visudo
(ký hiệu # cho biết lệnh này được thực thi với quyền root)
Trên Ubuntu, các giá trị mặc định trong file sudoers gồm có:
Defaults !lecture,!tty_tickets,!fqdn
root ALL=(ALL) ALL
%admin ALL=(ALL) ALL
Những khai báo trên được giải thích như sau:
  • Chỉ thị Default cho biết những tham số được khai báo mặc định cho hoạt động của sudo (sudo hoạt động với rất nhiều tham số, xem man sudoers để biết ý nghĩa của chúng), trong đó:
    • lecture là cờ điều khiển chế độ xuất một đoạn văn bản giống như “welcome” khi sudo được sử dụng. Với khai báo !lecture nghĩa là cờ này bị off, không được sử dụng. Khi sử dụng, cờ này có ba giá trị: “never” (chẳng bao giờ xuất văn bản), “once” (xuất văn bản ở lần sử dụng sudo đầu tiên), “always” (xuất văn bản bất cứ khi nào dùng sudo) trong đó “once” là giá trị mặc định. Chẳng hạn khi bật lên ở chế độ thường trực (always) thì khai báo như sau:lecture=”always”, và mỗi lần bạn dùng sudo sẽ thấy như sau:training@honey:/home/t3318$ sudo apt-get clean
      We trust you have received the usual lecture from the local System Administrator. It usually boils down to these three things:
      #1) Respect the privacy of others.
      #2) Think before you type.
      #3) With great power comes great responsibility.
      [sudo] password for training:>
    • tty_tickets là cờ cho biết sudo sẽ xác thực user theo từng “tty”. Điều này có nghĩa là nếu bật cờ này lên, mỗi khi bạn mở một console hay terminal khác và sử dụng sudo thì phải gõ mật khẩu lại, cho dù bạn có nằm trong timestamp 5 phút hay không. Nếu tắt cờ này đi, trong thời gian 5 phút bạn có thể dùng sudo mà không phải gõ mật khẩu, cho dù ở tty nào. Cờ này có giá trị boolean, “true” hoặc “false”.
    • fqdn là cờ báo hiệu có cần phải khai báo tên máy đầy đủ trong file sudoers hay không. Nghĩa là nếu bật cờ này lên thì trong phần hostname, thay vì ghi kythuatmaytinh, bạn phải ghi đầy đủ kythuatmaytinh.wordpress.com. Cờ này cũng có giá trị boolean.
    • Như vậy ta có thể thấy Ubuntu thiết lập mặc định cho cơ chế sudo của mình là: không xuất văn bản khi dùng sudo, không xác nhận theo tty và không cần phải khai báo tên domain đầy đủ trong file sudoers.
  • Chỉ thị ” root ALL=(ALL) ALL” tuân theo đúng cú pháp thường gặp, có nghĩa là người dùng root, trên tất cả các máy, có thể mượn quyền tất cả các người dùng, để thực thi tất cả các lệnh.
  • Chỉ thị “%admin ALL=(ALL) ALL” cũng tuân theo cú pháp đó, có nghĩa là nhóm người dùng admin, trên tất cả các máy, có thể mượn quyền tất cả các người dùng, để thực thi tất cả các lệnh.
Giả sử ta muốn cho thêm người dùng user1 được phép tắt máy của mình, ta thêm vào dòng:
user1 localhost=/sbin/shutdown
Nếu không khai báo rõ (target-users), sudo sẽ tự gán cho người triệu gọi sudo quyền owner của lệnh đó.
Ta cho phép người dùng monitor được phép khởi động lại apache server trên máy linux01 như sau:
monitor linux01= /etc/init.d/apache2 restart
Bây giờ ta có thể copy file sudoer này lên máy linux01 để áp dụng luật cho user monitor.
Save file lại bằng tổ hợp phím Ctrl-O và thoát ra bằng tổ hợp phím Ctrl-X, lúc này các rule đã có tác dụng.

Một số ví dụ thực tế khác

a) Cho phép user subadmin được thực thi nhiều lệnh với quyền root
subadmin ALL=(root) /sbin/shutdown, /bin/kill, /etc/init.d/httpd
b) Cho phép user subadmin được tắt máy mà không cần phải xác nhận bằng mật khẩu
subadmin localhost= NOPASSWD: /sbin/shutdown
c) Cho phép user subadmin được thực hiện bất kỳ lệnh nào trong /usr/bin ở máy linux01
subadmin linux01 = /usr/bin/*

Đọc thêm