Sử dụng CmndAlias ALL
sẽ không bao giờ an toàn
Có 1000 cách để chạy service network restart
mà không cần làm sudo service network restart
. Dưới đây là một ví dụ về những gì người dùng nghịch ngợm có thể thử:
$ echo "service network restart" > /tmp/hax
$ chmod a+x /tmp/hax
$ sudo /tmp/hax
Nếu bạn cung cấp cho người dùng ALL
bí danh lệnh, và sau đó thử tạo một danh sách đen, họ sẽ luôn có thể tìm cách xung quanh nó. Danh sách đen bash, và họ sẽ sử dụng python. Danh sách đen trăn, và họ sẽ sử dụng Perl. Danh sách đen Perl, và họ sẽ sử dụng PHP. Không ai muốn điều đó!
Nếu bạn thực sự không muốn ai đó làm gì đó, bạn nên làm như Thomas nói và tạo một danh sách trắng những thứ họ đang có phép làm.
Thiết lập danh sách trắng với một ngoại lệ
Một ví dụ về danh sách trắng nhỏ có loại trừ có thể được tìm thấy ở gần cuối man sudoers
:
pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
The user pete is allowed to change anyone's password except for root on the HPPA
machines. Note that this assumes passwd(1) does not take multiple user names
on the command line.
(Trong thực tế, ví dụ này từ trang chủ là không an toàn và có thể được khai thác để thay đổi mật khẩu của root! Xem các bình luận bên dưới để biết cách.)
Chúng tôi có thể cố gắng thích ứng với trường hợp của bạn, để cung cấp tất cả service
các lệnh cho nhóm nhân viên, nhưng loại trừ các service network
lệnh liên quan đến bạn:
%staff ALL = /usr/sbin/service *, \
! /usr/sbin/service *network*, \
! /usr/sbin/service *NetworkManager*
(Ở ALL
vị trí đó đề cập đến Host_Alias, không phải Cmnd_Alias - khó hiểu phải không?)
Người dùng sẽ không thể chạy sudo bash
hoặc sudo tee
hoặc sudo wget
hoặc sudo /path/to/malicious_script
. Bạn có thể liệt kê thêm các lệnh quản trị viên cho người dùng của mình nếu bạn cẩn thận. Chỉ cần cụ thể!
Lưu ý: Tôi đã thêm từ *
trước vào từ network
trên, chỉ trong trường hợp một cờ vô hại được thêm vào service
công cụ trong tương lai. Hãy tưởng tượng một --verbose
lá cờ đã được thêm vào trong tương lai, sau đó người dùng sẽ có thể chạy như sau:
$ sudo service --verbose network restart
Vì vậy, chúng tôi cần phải *
tiêu thụ bất kỳ cờ trước tên dịch vụ. Một nhược điểm là điều này có thể chặn các dịch vụ khác mà bạn không thực sự quan tâm đến người dùng đang chạy, ví dụ như một dịch vụ được gọi safe-network
hoặc network-monitor
cũng sẽ bị từ chối.
Cho phép người dùng chỉnh sửa tệp bằng quyền của nhóm
Dưới đây bạn có thể tìm thấy nhiều nỗ lực khác nhau bằng cách sử dụng rnano
thông qua sudo
để cho phép người dùng chỉnh sửa tệp hoặc tệp. Nhưng thực sự chúng phức tạp và nguy hiểm hơn mức cần thiết.
Một giải pháp đơn giản và an toàn hơn nhiều là thay đổi quyền của nhóm trên các tệp cụ thể mà bạn muốn mở quyền chỉnh sửa. Dưới đây là một vài ví dụ:
### Give steve the ability to edit his nginx config:
$ chgrp steve /etc/nginx/sites-available/steves_dodgy_project
$ chmod g+rw /etc/nginx/sites-available/steves_dodgy_project
### Let all members of the staff group edit the group_website config:
$ chgrp staff /etc/nginx/sites-available/group_website
$ chmod g+rw /etc/nginx/sites-available/group_website
Nếu bạn cần kiểm soát chi tiết hơn (ví dụ: quyền truy cập chỉ cho 3 người dùng, nhưng không phải tất cả nhân viên), bạn có thể tạo một nhóm mới bằng cách sử dụng addgroup
lệnh và chỉ thêm một vài người dùng vào đó.
Cho phép người dùng chỉnh sửa một tập tin thông qua sudo
Phần còn lại của câu trả lời này đã trở thành một cuộc điều tra về việc dễ dàng để lại lỗ hổng trong sudo
cấu hình của bạn khi cố gắng cung cấp tính linh hoạt cho người dùng của bạn. Tôi không khuyên bạn nên làm bất kỳ điều sau đây!
Nếu bạn muốn cấp cho người dùng quyền truy cập để chỉnh sửa một tệp cụ thể, bạn có thể thử sử dụng rnano
:
%staff ALL = /bin/rnano /etc/nginx/sites-available/host
rnano
sẽ chỉ cho phép họ chỉnh sửa các tập tin được chỉ định. Điều đó rất quan trọng để ngăn chặn người dùng độc hại chỉnh sửa một dịch vụ mới bắt đầu (ví dụ /etc/init.d/urandom
) và thêm một dòng vào đó sẽ chạy service network restart
.
Thật không may, tôi không tìm thấy cách nào để hạn chế rvim
đủ (người dùng vẫn có thể mở bất kỳ tệp nào bằng cách sử dụng :e
), vì vậy chúng tôi bị mắc kẹt nano
.
Thật không may, cho phép người dùng chỉnh sửa nhiều tệp khó hơn nhiều ...
Để người dùng chỉnh sửa nhiều tệp (khó hơn mức cần thiết)
1. Cách tiếp cận không an toàn
Hãy cẩn thận của các ký tự đại diện! Nếu bạn cung cấp quá nhiều tính linh hoạt (hoặc bất kỳ tính linh hoạt nào), nó có thể được khai thác:
%staff ALL = /bin/rnano /etc/nginx/sites-available/* # UNSAFE!
Trong trường hợp này, người dùng độc hại sẽ có thể chỉnh sửa bất kỳ tập lệnh dịch vụ mới bắt đầu nào khác, rồi chạy nó:
$ sudo rnano /etc/nginx/sites-available/../../../any/file/on/the/system
(Sudo thực sự ngăn chặn .
và ..
mở rộng lệnh, nhưng tiếc là không phải trên các đối số.)
Tôi đã hy vọng một cái gì đó như thế này có thể hoạt động, nhưng nó vẫn không an toàn:
%staff ALL = /bin/rnano /etc/nginx/sites-available/[A-Za-z0-9_-]* # UNSAFE!
Vì sudo
hiện tại chỉ cung cấp các mẫu toàn cầu , điều đó *
sẽ phù hợp với bất cứ điều gì - nó không phải là một biểu thức chính quy!
(Chỉnh sửa: Tôi đã cân nhắc nếu bạn có thể thoát khỏi tình trạng trên trong tình huống của mình, vì không có thư mục con bên dưới sites-available
. Chúng tôi đã yêu cầu một char được khớp sau thư mục và /..
sẽ thất bại sau tên tệp. Tuy nhiên, đây không phải là một giải pháp khả thi, bởi vì rnano
chấp nhận nhiều đối số. Và dù sao thì nói chung điều này vẫn không an toàn trên một thư mục có các thư mục con!)
Ngay cả khi chúng tôi không có thư mục con và chúng tôi loại trừ bất kỳ dòng nào có chứa /../
, quy tắc cung cấp toàn *
cầu vẫn có thể được khai thác, bởi vì rnano
chấp nhận nhiều đối số (đi qua chúng <C-X>
và không gian được toàn cầu chấp nhận *
.
$ rnano /etc/nginx/sites-available/legal_file /then/any/file/on/the/system
2. Đẩy phong bì (cuối cùng cũng không an toàn)
Vậy điều gì sẽ xảy ra nếu chúng ta từ chối bất kỳ dòng nào chứa khoảng trắng hoặc cố gắng tiếp cận /..
? Sau đó, một giải pháp khả thi cuối cùng có thể là:
# I tried hard to make this safe, but in the end I failed again.
# Please don't use this unless you are really smart or really stupid.
%staff ALL = /bin/rnano /etc/nginx/sites-available/*, \
! /bin/rnano */..*, \
! /bin/rnano /etc/nginx/sites-available/, \
! /bin/rnano */., \
! /bin/rnano * *
# CONCLUSION: It is still NOT SAFE if there are any subfolders, due to
# the bug in rnano described below.
Chúng tôi chấp nhận bất cứ điều gì "dưới" thư mục nhưng chúng tôi cũng từ chối bất kỳ cuộc gọi đến rnano
nếu /..
hay /.
hoặc
được thông qua, hoặc khi thư mục được nhắm mục tiêu trực tiếp. (Về mặt kỹ thuật /.
loại trừ làm cho loại trừ trở nên /..
dư thừa, nhưng tôi đã để lại cả hai cho rõ ràng.)
Tôi tìm thấy thư mục và các /.
loại trừ là cần thiết bởi vì nếu không thì người dùng có thể nhắm mục tiêu chính thư mục đó. Bây giờ bạn có thể nghĩ rnano
sẽ chặn nếu chỉ vào một thư mục, nhưng bạn sẽ sai. Trên thực tế, phiên bản của tôi (2.2.6-1ubfox1) bắt đầu với một cảnh báo nhẹ và một tệp trống, sau đó <C-X>
yêu cầu tôi nhập bất kỳ tên tệp nào tôi muốn lưu vào, mở một vectơ tấn công mới! Ít nhất là nó đã từ chối ghi đè lên một tệp hiện có (trong một thử nghiệm tôi đã làm). Dù sao, vì không có cách nào để vào danh sách đen các thư mục con với sudo, chúng tôi phải kết luận rằng phương pháp này một lần nữa không an toàn. Xin lỗi người dùng!
Khám phá này khiến tôi nghi ngờ về tính kỹ lưỡng của nano
chế độ "bị hạn chế". Họ nói rằng một chuỗi chỉ mạnh như liên kết yếu nhất của nó. Tôi bắt đầu cảm thấy sự kết hợp của sudo
ma thuật đen trong danh sách đen và rnano
có thể không an toàn hơn một chuỗi hoa cúc.
3. Cách tiếp cận an toàn nhưng có giới hạn
Các quả cầu rất hạn chế - chúng không cho phép chúng ta ghép một lớp nhân vật nhiều lần. Bạn có thể cung cấp nhiều chỉnh sửa tệp, nếu tất cả tên tệp của bạn có cùng độ dài (trong trường hợp này được host
theo sau bởi một chữ số):
%staff ALL = /bin/rnano /etc/nginx/sites-available/host[0-9] # SAFE
Nhưng nếu bạn muốn cấp cho người dùng quyền truy cập để chỉnh sửa các tệp khác nhau, bạn có thể cần chỉ định rõ ràng từng tệp và mọi tệp:
%staff ALL = /bin/rnano /etc/nginx/sites-available/hothost \
/bin/rnano /etc/nginx/sites-available/coldhost \ # SAFE
/bin/rnano /etc/nginx/sites-available/wethost \
/bin/rnano /etc/nginx/sites-available/steves_dodgy_project
Đừng bị cám dỗ để sử dụng*
bất cứ lúc nào. Xem phần 1. và 2. ở trên để biết lý do! Hãy nhớ rằng: một cú trượt nhỏ có thể làm tổn hại đến toàn bộ tài khoản siêu người dùng và toàn bộ hệ thống.
4. Viết trình kiểm tra đối số của riêng bạn (an toàn là trách nhiệm của bạn)
Tôi hy vọng họ sẽ thêm hỗ trợ regex sudo
trong tương lai; nó có thể giải quyết rất nhiều vấn đề nếu được sử dụng đúng cách. Nhưng chúng ta cũng có thể cần khả năng kiểm tra các thuộc tính của đối số (chỉ cho phép các tệp, chỉ thư mục hoặc chỉ một số cờ nhất định).
Nhưng có một cách thay thế để tạo sự linh hoạt trong sudo. Vượt qua
%staff ALL = /root/bin/staffedit *
Sau đó viết staffedit
tập lệnh của riêng bạn hoặc có thể thực thi để kiểm tra xem các đối số được người dùng chuyển qua có hợp pháp không và chỉ thực hiện yêu cầu của họ nếu có.
networking
vànetwork-manager
? Ngoài ra, tại sao người dùng của bạn cósudo
quyền truy cập? Họ không nên trừ khi bạn muốn họ có đầy đủ quyền root.