Làm thế nào để ngăn người dùng sudo chạy các lệnh cụ thể?


29

Tôi có một thiết lập mạng rất nhạy cảm và tôi thực sự không muốn làm hỏng nó. Mạng của tôi bao gồm một nhóm người dùng có đặc quyền sudo.

Tôi muốn ngăn họ chạy

service NetworkManager restart
service network restart

các lệnh.

Có cách nào tôi có thể đạt được điều này?


Phân phối nào bạn đang sử dụng? Tên dịch vụ là distro cụ thể và tôi không biết bất kỳ distro nào sử dụng tên bạn có ở đó. Bạn có nghĩa networkingnetwork-manager? Ngoài ra, tại sao người dùng của bạn có sudoquyền truy cập? Họ không nên trừ khi bạn muốn họ có đầy đủ quyền root.
terdon

@terdon Mình đã giải quyết xong. Cảm ơn bạn. Tôi không thể đăng nó dưới dạng câu trả lời vì tôi là người dùng mới
shekhar

Có bạn có thể, xin vui lòng làm. Tôi cũng muốn biết câu trả lời bạn tìm thấy.
terdon

@terdon chắc chắn nhưng nó nói rằng tôi cần đợi 8 giờ để đăng câu trả lời của riêng mình vì tôi thậm chí không có 10 danh tiếng
shekhar

1
Ah, vâng, xin lỗi, bạn thực sự cần phải chờ đợi. Tôi vừa mới nâng cấp, bạn có đại diện ngay bây giờ :)
terdon

Câu trả lời:


47

Sử dụng CmndAlias ALL sẽ không bao giờ an toàn

Có 1000 cách để chạy service network restartmà 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ả servicecác lệnh cho nhóm nhân viên, nhưng loại trừ các service networklệnh liên quan đến bạn:

%staff ALL =   /usr/sbin/service *,                            \
             ! /usr/sbin/service *network*,                    \
             ! /usr/sbin/service *NetworkManager*

(Ở ALLvị 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 bashhoặc sudo teehoặc sudo wgethoặ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ừ networktrên, chỉ trong trường hợp một cờ vô hại được thêm vào servicecông cụ trong tương lai. Hãy tưởng tượng một --verboselá 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-networkhoặc network-monitorcũ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 rnanothô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 addgrouplệ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 sudocấ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

rnanosẽ 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 ...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!

sudohiệ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ì rnanochấ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ì rnanochấ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 rnanonế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ĩ rnanosẽ 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 nanochế độ "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 sudoma thuật đen trong danh sách đen và rnanocó 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 hosttheo 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 sudotrong 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 staffedittậ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ó.


5
Câu trả lời này mất nhiều thời gian, nhưng cuối cùng tôi nghĩ tôi hiểu cách thức hoạt động của sudo. Tôi đã từ bỏ trong những dịp khác nhau trong quá khứ, thấy ALL=(ALL:ALL) ALLquá thiếu ngữ nghĩa, nhưng tôi luôn cho rằng ở đâu đó nó sẽ có một trình kiểm tra đối số đàng hoàng ... Tôi đã sai. Nó thực sự rất hạn chế. Ngay cả loại trừ gốc passwd được cung cấp trong trang man cũng có thể bị phá vỡ bằng một đối số dòng lệnh đơn giản , sudo passwd -q root. Vâng, các tác giả sudo đã liệt kê [một số lựa chọn thay thế] (sudo.ws/sudo/other.html) trên trang web của họ. Tôi hy vọng họ sẽ thêm hỗ trợ regex trong tương lai.
joeytwiddle

Bạn có đặc biệt sử dụng rnanotrong mô tả của mình ở đây không vì đây là phiên bản nano thiếu chức năng 'lưu dưới dạng'? Tôi không quen thuộc với chương trình.
Shadur

Vâng. Nếu chúng tôi quan tâm đến bảo mật, trình chỉnh sửa chỉ nên chỉnh sửa một tệp được chỉ định và không thể mở trình bao. Để biết thông tin, $ man nanosau đó/-R<Enter>
joeytwiddle

Sửa chữa: Để phá vỡ ví dụ pete, -qphải đến sau : sudo passwd root -q. Ví dụ pete có thể được làm cứng bằng cách loại trừ *root*.
joeytwiddle

Xem xét sử dụng sudoeditđể kích hoạt an toàn sửa đổi tập tin với sudo.
Totor

5

Đầu tiên, mở tập tin sudoers với sudo visudo. Thêm user ALL=!/usr/sbin/serviceý chí, IIRC, không cho phép servicelệnh cho người dùng user.

Nguồn: http://nixcraft.com/showthread.php/15132-Sudo-Exclude-Commands-And-Disable-sudo-su-Bash-Shell


Điều này cũng sẽ ngừng chạy các dịch vụ khác và tôi không muốn điều đó. Cảm ơn câu trả lời. :)
shekhar

trong khi câu trả lời của bạn không giúp tôi chính xác nhưng nó giúp tìm ra giải pháp cảm ơn bạn. nhưng bạn biết hoặc để cung cấp cho bạn upvote hoặc đăng câu trả lời làm việc của tôi, tôi không có đủ danh tiếng. Tôi chắc chắn sẽ cảm ơn tôi một khi tôi. Cảm ơn bạn.
shekhar

2
Vâng, nhưng vẫn, như những người khác đã tuyên bố, bạn phải rất cẩn thận với điều đó. Có nhiều cách để có được quyền truy cập. Bất kỳ lệnh nào có thể sinh ra một vỏ và như vậy. Cách dễ dàng hơn để tìm ra những lệnh họ thực sự cần và cho phép chúng, thay vì cố gắng loại trừ tất cả những lệnh "bị cấm".
Bonsi Scott

3
Danh sách trắng là không thể nhầm lẫn trong nhiều kịch bản. Mục tiêu thực sự có thể không phải là ngăn cản họ làm điều gì đó, mà là để ngăn họ làm điều gì đó xấu do nhầm lẫn mà không hạn chế chúng. Danh sách đen là tốt trong những trường hợp này. Bạn đưa vào danh sách đen những cách mà người dùng hợp lý sẽ thực hiện nhiệm vụ. Nhưng danh sách đen thông qua sudo có thể không đủ - mọi người có thể và sử dụng 'sudo bash'. Một cách tiếp cận sẽ là bọc lệnh 'dịch vụ' và trong trường hợp bạn không muốn họ sử dụng, hãy thông báo cho họ. Nhưng bạn sẽ không bao giờ liệt kê tất cả các hành động tốt trong danh sách trắng, cũng không phải tất cả các hành động xấu trong danh sách đen.
Bob Kerns

1
Tôi đồng ý với bạn Bob. Để cho phép linh hoạt, không cho phép truy cập đầy đủ, bạn thường sẽ cần phải cuộn giải pháp của riêng mình, dưới dạng tập lệnh trợ giúp và chỉ đưa vào danh sách trắng tập lệnh đó. danh sách trắng sudo có thể làm những gì bạn cần, nhưng thường thì chúng sẽ quá hạn chế hoặc quá dễ khai thác.
joeytwiddle

5

Tôi đã tìm được giải pháp.

Tôi đã mở terminal và thay đổi thành người dùng root và su -sau đó tôi đã gõ visudođể chỉnh sửa.

sau đó tôi đã viết những dòng như

user ALL=!/etc/init.d/NetworkManager restart
user ALL=!/etc/init.d/network restart

Sau đó, tôi đã lưu và đóng và khởi động lại quá.

Bây giờ Nếu tôi đang gõ service network restarthoặc không service NetworkManager restartthì nó không cho phép tôi và báo lỗi như

Sorry user is not allowed to execute '/sbin/service NetowkrManager restart' as root on localhost.localdomain

và tương tự cho service network restartlệnh cũng.


12
Điều đó sẽ làm việc cho người dùng chưa có kinh nghiệm và không có kinh nghiệm, nhưng nó rất dễ phá vỡ các hạn chế sudo, (ví dụ sudo cp -p /etc/init.d/network /etc/init.d/network-not-in-sudovà sau đó sudo /etc/init.d/network-not-in-sudo restart). Đó là lý do tại sao an toàn hơn nhiều khi tạo các vùi thay vì loại trừ trong tệp sudoers, ví dụ: nêu rõ các dịch vụ mà họ được phép tương tác.
Thomas

Mọi thứ mà 'khởi động lại mạng dịch vụ' đều có, bạn có thể thực hiện với các lệnh khác, chẳng hạn như các lệnh trong tập lệnh init.d của mạng. Tôi thậm chí sẽ không cố gắng liệt kê chúng ở đây. Nhưng nếu bạn muốn, ví dụ, thực sự ngăn chặn sửa đổi trạng thái giao diện, thì chính sách SELinux dường như là hướng đi của tôi. Đây là một chủ đề phức tạp, nhưng khi một danh sách trắng quá hạn chế hoặc nặng nề, và một danh sách đen là không đủ, đó có lẽ là lựa chọn tốt nhất của bạn. Nó được triển khai trong kernel và cho phép bạn hạn chế quyền truy cập vào giao diện mạng (và các tài nguyên khác) ngay cả với người dùng sudo'd.
Bob Kerns

Nếu có thể với SELinux thì sẽ hài lòng hơn. @BobKerns Cảm ơn bạn. Tôi sẽ cố gắng theo cách đó.
shekhar

3

Câu trả lời thực sự cho điều này là bạn không thể thực sự ngăn chặn điều này. Bạn có thể ngăn người khác vô tình chạy lệnh đó thông qua các phương thức được mô tả trong các câu trả lời khác, nhưng nếu ai đó thực sự muốn chạy nó và nằm trong danh sách sudoers, họ có thể chạy nó. Ví dụ, họ có thể làm như sau:

joe@box:~$ sudo bash root@box:~# service network restart

Hoặc một lệnh thú vị khác mà họ có thể sử dụng để tránh các hạn chế của bạn trong tệp sudoers:

sudo visudo

Câu chuyện dài, nếu bạn có thể sudo và nó không bị hạn chế chạy các lệnh cụ thể, bạn có thể làm bất cứ điều gì bạn muốn. Ngay cả khi bạn giới hạn chúng trong một nhóm lệnh nhất định, bạn phải đảm bảo rằng người dùng không thể sao chép một số lệnh khác mà họ muốn chạy cùng tên với lệnh mà họ có quyền chạy ( chẳng hạn như bằng cách ghi đè lệnh mà họ có quyền chạy.)


Vâng. Người ta nên tránh các lệnh có thể sinh ra một lớp vỏ từ bên trong.
Bonsi Scott

1
Vấn đề là, đó không phải là các lệnh bạn muốn bảo vệ, mà là trạng thái của các đối tượng kernel, chẳng hạn như bảng định tuyến, giao diện, v.v. - bất kể lệnh nào (hoặc lệnh gọi hệ thống) được sử dụng. Và bạn muốn bảo vệ nó khỏi một số, nhưng không phải tất cả, người dùng root. SELinux được thiết kế xung quanh loại kịch bản này. Nhưng trước tiên, tôi sẽ bắt đầu với một đánh giá về lý do tại sao tất cả những người dùng này có quyền truy cập sudo. Nếu họ chỉ cần làm một vài điều cụ thể, các hoạt động danh sách trắng trong sudoers có thể là tất cả những gì bạn cần.
Bob Kerns

2

Sử dụng tường lửa để hạn chế người dùng với hộp cát.

https://github.com/netblue30/firejail/

Đặt firejail làm shell thay vì bash trong / etc / passwd, cho mọi người dùng bạn muốn hạn chế. Nó rất dễ sử dụng và có một tài liệu tốt.

Thí dụ:

user:x:1000:1000:user:/home/user:/usr/bin/firejail
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.