Việc tách biệt đặc quyền là một trong những nguyên tắc bảo mật cơ bản được triển khai trong các hệ điều hành Linux và các hệ thống tương tự Unix. Người dùng thông thường vận hành với đặc quyền hạn chế nhằm giới hạn phạm vi ảnh hưởng chỉ trong môi trường của riêng họ, không lan ra toàn hệ thống.
Một người dùng đặc biệt, gọi là root, có quyền siêu người dùng. Đây là tài khoản quản trị không bị ràng buộc bởi những hạn chế mà tài khoản người dùng thông thường phải tuân theo. Người dùng có thể thực hiện các lệnh với quyền root hoặc quyền siêu người dùng theo nhiều cách khác nhau.
Trong bài viết này, chúng ta sẽ thảo luận cách để có được quyền root một cách chính xác và an toàn, với trọng tâm đặc biệt vào việc chỉnh sửa file /etc/sudoers.
Hướng dẫn dưới đây được thực hiện trên một máy chủ Ubuntu 20.04, tuy nhiên hầu hết các bản phân phối Linux hiện đại như Debian và CentOS đều hoạt động theo cách tương tự.
Hướng dẫn này giả định rằng bạn đã hoàn thành quá trình thiết lập máy chủ ban đầu như đã đề cập ở phần giới thiệu.
Đăng nhập vào máy chủ với tư cách là người dùng thông thường (không phải root) và tiếp tục theo các bước dưới đây.
Lưu ý: Hướng dẫn này đi sâu vào vấn đề leo thang đặc quyền và file sudoers. Nếu bạn chỉ cần thêm quyền sudo cho người dùng, hãy tham khảo các hướng dẫn “Cách tạo người dùng có quyền sudo” dành cho Ubuntu và CentOS.
Cách lấy quyền root
Có ba cách cơ bản để có được quyền root, mỗi cách có mức độ phức tạp khác nhau.
Đăng nhập với tư cách root
Cách đơn giản và trực tiếp nhất để có quyền root là đăng nhập trực tiếp vào máy chủ với tài khoản root.
Nếu bạn đăng nhập vào máy tính cục bộ (hoặc sử dụng tính năng console ngoài luồng trên máy chủ ảo), hãy nhập “root” làm tên người dùng tại màn hình đăng nhập và nhập mật khẩu root khi được yêu cầu.
Nếu bạn đăng nhập qua SSH, hãy chỉ định người dùng root trước địa chỉ IP hoặc tên miền trong chuỗi kết nối SSH, như sau:
ssh root@server_domain_or_ip
Nếu bạn chưa thiết lập SSH keys cho tài khoản root, hãy nhập mật khẩu root khi được yêu cầu.
Sử dụng su để trở thành root
Đăng nhập trực tiếp với tài khoản root thường không được khuyến khích vì dễ dẫn đến việc vô tình sử dụng hệ thống cho các tác vụ không liên quan đến quản trị – một hành động có thể gây nguy hiểm.
Cách tiếp theo để có được quyền siêu người dùng là cho phép bạn chuyển đổi sang tài khoản root bất cứ khi nào cần.
Chúng ta có thể làm điều này bằng cách sử dụng lệnh su, viết tắt của “substitute user”. Để có quyền root, hãy gõ:
su
Bạn sẽ được yêu cầu nhập mật khẩu của tài khoản root, sau đó bạn sẽ được chuyển sang phiên làm việc của root.
Khi bạn hoàn thành các tác vụ cần quyền root, quay trở lại shell thông thường bằng cách gõ:
exit
Sử dụng sudo để thực thi lệnh với quyền root
Cách cuối cùng để có quyền root mà chúng ta sẽ thảo luận là sử dụng lệnh sudo.
Lệnh sudo cho phép bạn thực thi các lệnh đơn lẻ với quyền root mà không cần phải mở một shell mới. Cú pháp thực hiện như sau:
Khác với lệnh su, lệnh sudo sẽ yêu cầu nhập mật khẩu của người dùng hiện tại, không phải mật khẩu của root.
Do các tác động về bảo mật, quyền sudo không được cấp cho người dùng theo mặc định và cần phải được thiết lập trước khi hoạt động đúng. Hãy xem hướng dẫn “Cách tạo người dùng có quyền sudo” dành cho Ubuntu và CentOS để biết cách thiết lập người dùng có quyền sudo.
Trong phần tiếp theo, chúng ta sẽ thảo luận cách sửa đổi cấu hình sudo một cách chi tiết.
Visudo là gì?
Lệnh sudo được cấu hình thông qua một file nằm tại /etc/sudoers.
Cảnh báo: Đừng bao giờ chỉnh sửa file này bằng trình soạn thảo văn bản thông thường! Luôn luôn sử dụng lệnh visudo để chỉnh sửa!
Vì cú pháp không đúng trong file /etc/sudoers có thể khiến hệ thống bị hỏng, dẫn đến không thể lấy được đặc quyền nâng cao, nên việc sử dụng lệnh visudo để chỉnh sửa file này là hết sức quan trọng.
Lệnh visudo mở một trình soạn thảo văn bản như bình thường, nhưng sẽ kiểm tra cú pháp của file khi lưu lại. Điều này giúp ngăn chặn các lỗi cấu hình làm gián đoạn các hoạt động sudo – có thể là cách duy nhất để lấy được quyền root.
Theo truyền thống, visudo mở file /etc/sudoers với trình soạn thảo vi. Tuy nhiên, Ubuntu đã cấu hình visudo sử dụng trình soạn thảo nano thay thế.
Nếu bạn muốn đổi lại về vi, hãy thực hiện lệnh sau:
sudo update-alternatives --config editor
Output
Chọn số tương ứng với trình soạn thảo bạn muốn sử dụng.
Trên CentOS, bạn có thể thay đổi giá trị này bằng cách thêm dòng sau vào file ~/.bashrc
:
export EDITOR=`which name_of_editor`
Sau đó, hãy nạp lại file để áp dụng thay đổi:
. ~/.bashrc
Sau khi đã cấu hình visudo, thực thi lệnh để truy cập file /etc/sudoers:
sudo visudo
Cách chỉnh sửa file sudoers
Bạn sẽ thấy nội dung file /etc/sudoers
hiện ra trong trình soạn thảo bạn đã chọn.
Tôi đã sao chép và dán nội dung file từ Ubuntu 20.04, sau khi đã loại bỏ các chú thích. File /etc/sudoers
của CentOS có nhiều dòng hơn, một số dòng sẽ không được thảo luận trong hướng dẫn này.
Các dòng mặc định
Dòng đầu tiên, Defaults env_reset
, đặt lại môi trường terminal để loại bỏ các biến của người dùng. Đây là biện pháp an toàn nhằm xóa các biến môi trường có thể gây hại khỏi phiên sudo.
Dòng thứ hai, Defaults mail_badpass
, yêu cầu hệ thống gửi thông báo khi có nỗ lực nhập sai mật khẩu sudo tới người dùng được cấu hình (mặc định là tài khoản root).
Dòng thứ ba, bắt đầu với Defaults secure_path=...
, chỉ định PATH (các thư mục mà hệ thống sẽ tìm kiếm ứng dụng) được sử dụng cho các lệnh sudo. Điều này giúp ngăn chặn việc sử dụng các đường dẫn của người dùng có thể gây hại.
Các dòng quyền người dùng
Dòng thứ tư quy định quyền sudo của người dùng root, khác với các dòng trước đó. Hãy cùng xem các trường trong dòng này có nghĩa là gì:
-
root ALL=(ALL:ALL) ALL
: Trường đầu tiên chỉ định tên người dùng mà quy tắc này áp dụng (root). -
Trường thứ hai “ALL” cho biết quy tắc này áp dụng cho tất cả các máy chủ.
-
Trường thứ ba “ALL” cho biết người dùng root có thể chạy lệnh dưới tư cách của tất cả các người dùng.
-
Trường thứ tư “ALL” cho biết người dùng root có thể chạy lệnh dưới tư cách của tất cả các nhóm.
-
Trường cuối cùng “ALL” chỉ định rằng các quy tắc này áp dụng cho tất cả các lệnh.
Có nghĩa là, tài khoản root có thể chạy bất kỳ lệnh nào bằng sudo, với điều kiện họ cung cấp đúng mật khẩu.
Các dòng quyền nhóm
Hai dòng tiếp theo tương tự như dòng quyền người dùng, nhưng quy định các quy tắc sudo cho nhóm người dùng.
Các tên bắt đầu bằng dấu % chỉ định tên nhóm.
Ở đây, chúng ta thấy nhóm admin có thể thực thi bất kỳ lệnh nào dưới tư cách của bất kỳ người dùng nào trên bất kỳ máy chủ nào.
Tương tự, nhóm sudo có cùng đặc quyền, nhưng có thể chạy lệnh dưới tư cách của bất kỳ nhóm nào.
Dòng bao gồm /etc/sudoers.d
Dòng cuối cùng có vẻ giống như là chú thích lúc đầu:
. . . #includedir /etc/sudoers.d
Các file trong thư mục này tuân theo các quy tắc giống như file /etc/sudoers. Bất kỳ file nào không kết thúc bằng ~ và không có dấu chấm (.) trong tên file sẽ được đọc và nối vào cấu hình sudo.
Điều này chủ yếu nhằm mục đích cho phép các ứng dụng thay đổi quyền sudo khi cài đặt. Việc gom tất cả các quy tắc liên quan vào một file riêng biệt trong thư mục /etc/sudoers.d sẽ giúp dễ dàng nhận biết quyền của từng tài khoản và có thể đảo ngược các thay đổi một cách dễ dàng mà không cần thao tác trực tiếp trên file /etc/sudoers.
Như với file /etc/sudoers, bạn luôn nên chỉnh sửa các file trong thư mục /etc/sudoers.d bằng lệnh visudo. Cú pháp để chỉnh sửa các file này là:
sudo visudo -f /etc/sudoers.d/file_to_edit
Cách cấp quyền sudo cho người dùng
Việc thường gặp nhất khi quản lý quyền sudo là cấp quyền sudo cho một người dùng mới. Điều này hữu ích nếu bạn muốn cấp quyền quản trị đầy đủ cho một tài khoản.
Cách dễ nhất để làm điều này trên hệ thống được thiết lập với một nhóm quản trị chung, như hệ thống Ubuntu trong hướng dẫn này, là thêm người dùng vào nhóm đó.
Ví dụ, trên Ubuntu 20.04, nhóm sudo có toàn bộ quyền quản trị. Chúng ta có thể cấp cho người dùng quyền tương tự bằng cách thêm họ vào nhóm sudo như sau:
sudo usermod -aG sudo username
Lệnh gpasswd cũng có thể được sử dụng:
sudo gpasswd -a username sudo
Cả hai lệnh trên đều đạt được mục đích như nhau.
Trên CentOS, nhóm quản trị thường là wheel thay vì sudo:
sudo usermod -aG wheel username
Hoặc, sử dụng gpasswd:
sudo gpasswd -a username wheel
Trên CentOS, nếu việc thêm người dùng vào nhóm không có hiệu lực ngay lập tức, bạn có thể cần chỉnh sửa file /etc/sudoers
để bỏ chú thích dòng chứa tên nhóm:
sudo visudo
Trong file /etc/sudoers
, tìm đoạn:
. . . %wheel ALL=(ALL) ALL . . .
Giờ đây, khi đã nắm được cú pháp chung của file sudoers, hãy cùng tạo một số quy tắc mới.
Cách tạo bí danh
File sudoers có thể được tổ chức dễ dàng hơn bằng cách nhóm các mục theo các loại “bí danh”.
Ví dụ, chúng ta có thể tạo ra ba nhóm người dùng với các thành viên có phần giao nhau:
Sau đó, chúng ta cho phép thành viên của GROUPTWO cập nhật cơ sở dữ liệu apt bằng cách tạo quy tắc sau:
. . . GROUPTWO ALL = /usr/bin/apt-get update . . .
Cách thiết lập quy tắc tùy chỉnh
Nếu không chỉ định người dùng/nhóm để chạy lệnh, như ví dụ trên, sudo mặc định sẽ sử dụng tài khoản root.
Chúng ta cũng có thể cho phép thành viên của GROUPTHREE tắt máy và khởi động lại hệ thống bằng cách tạo “command alias” và sử dụng nó trong quy tắc của GROUPTHREE:
Ở đây, chúng ta tạo một bí danh lệnh có tên POWER chứa các lệnh tắt máy và khởi động lại. Sau đó, cho phép thành viên của GROUPTHREE thực thi các lệnh đó.
Chúng ta cũng có thể tạo “Run as” alias, thay thế phần chỉ định người dùng mà lệnh sẽ chạy dưới tư cách:
Lưu ý rằng các quy tắc phía sau sẽ ghi đè lên các quy tắc phía trước khi có sự xung đột.
Cách khóa quy tắc
Có một số cách để bạn có thể kiểm soát chặt chẽ hơn cách sudo phản ứng khi thực thi lệnh.
Lệnh updatedb của gói mlocate khá vô hại trên hệ thống chỉ có một người dùng. Nếu bạn muốn cho phép người dùng thực thi lệnh này với quyền root mà không cần nhập mật khẩu, có thể tạo quy tắc như sau:
Ví dụ, ta có thể có dòng:
Ví dụ, một số chương trình như less có thể tạo ra các lệnh khác từ bên trong giao diện của nó bằng cách gõ:
Để hạn chế điều này, bạn có thể sử dụng quy tắc:
. . . username ALL = NOEXEC: /usr/bin/less . . .
Thông tin khác
Có vài thông tin bổ sung hữu ích khi làm việc với sudo.
Nếu bạn chỉ định người dùng hoặc nhóm để “run as” trong file cấu hình, bạn có thể thực thi lệnh với tư cách của những người đó bằng cách sử dụng các tham số -u
và -g
tương ứng:
sudo -u run_as_user command sudo -g run_as_group command
Để tiện lợi, theo mặc định, sudo sẽ lưu lại thông tin xác thực của bạn trong một khoảng thời gian nhất định trên một terminal. Điều này có nghĩa là bạn sẽ không cần phải nhập lại mật khẩu cho đến khi khoảng thời gian đó hết hạn.
Vì lý do bảo mật, nếu bạn muốn xóa bộ nhớ đệm này sau khi đã thực hiện các lệnh quản trị, bạn có thể chạy:
sudo -k
Nếu bạn muốn “làm mới” lệnh sudo để không bị nhắc lại mật khẩu sau này, hoặc để gia hạn phiên sudo, bạn có thể gõ:
sudo -v
Khi được nhắc, bạn sẽ nhập mật khẩu, và mật khẩu đó sẽ được lưu lại cho các lần sử dụng sudo sau cho đến khi khoảng thời gian lưu trữ hết hạn.
Nếu bạn chỉ muốn xem các đặc quyền được định nghĩa cho tên người dùng của mình, hãy gõ:
sudo -l
Lệnh này sẽ liệt kê tất cả các quy tắc trong file /etc/sudoers áp dụng cho người dùng của bạn. Điều này giúp bạn nắm được những gì bạn có thể hay không thể làm với sudo dưới bất kỳ tư cách người dùng nào.
Có nhiều lần khi bạn thực hiện lệnh mà bị lỗi vì quên gõ sudo. Để tránh phải nhập lại lệnh, bạn có thể tận dụng tính năng của bash để “lặp lại lệnh cuối cùng”:
sudo !!
Dấu hai chấm cảm thán (!!) sẽ lặp lại lệnh cuối cùng. Chúng ta đặt sudo ở đầu để nhanh chóng chuyển lệnh từ không có đặc quyền sang có đặc quyền.
Nếu bạn muốn thử một chút vui, hãy thêm dòng sau vào file /etc/sudoers bằng cách sử dụng visudo:
sudo visudo
Trong file /etc/sudoers, thêm:
. . . Defaults insults . . .
Sau đó, sử dụng lệnh:
sudo -k sudo ls
Ví dụ output:
[sudo] password for demo: # enter an incorrect password here to see the results Your mind just hasn't been the same since the electro-shock, has it? [sudo] password for demo: My mind is going. I can feel it.
Kết luận
Bây giờ bạn đã có hiểu biết cơ bản về cách đọc và chỉnh sửa file sudoers, cũng như nắm được các phương pháp để lấy quyền root.
Hãy nhớ rằng, đặc quyền siêu người dùng không được cấp cho người dùng thông thường một cách tùy tiện. Điều quan trọng là bạn phải hiểu rõ tác dụng của từng lệnh khi chạy với quyền root. Hãy sử dụng các công cụ này một cách cẩn trọng, và khóa lại những chức năng không cần thiết để tăng cường bảo mật hệ thống.