ssh
theo rsh
truyền thống bằng cách sử dụng chương trình shell của người dùng từ tệp mật khẩu để thực hiện các lệnh.
Điều này có nghĩa là chúng ta có thể giải quyết vấn đề này mà không cần ssh
cấu hình theo bất kỳ cách nào.
Nếu bạn không muốn người dùng có thể có quyền truy cập shell, thì chỉ cần thay thế shell của người dùng đó bằng một tập lệnh. Nếu bạn nhìn vào, /etc/passwd
bạn sẽ thấy rằng có một trường chỉ định trình thông dịch lệnh shell cho mỗi người dùng. Tập lệnh được sử dụng làm vỏ cho cả đăng nhập tương tác của chúng ssh user@host
cũng như cho các lệnh ssh user@host command arg ...
.
Đây là một ví dụ. Tôi đã tạo một người dùng foo
có trình bao là một tập lệnh. Tập lệnh in thông báo my arguments are:
theo sau là các đối số của nó (mỗi đối số trên một dòng riêng biệt và trong dấu ngoặc nhọn) và kết thúc. Trong nhật ký trong trường hợp, không có đối số. Đây là những gì sẽ xảy ra:
webserver:~
foo@localhost's password:
Linux webserver [ snip ]
[ snip ]
my arguments are:
Connection to localhost closed.
Nếu người dùng cố gắng chạy một lệnh, nó sẽ giống như sau:
webserver:~
foo@localhost's password:
my arguments are:
<-c>
<cat /etc/passwd>
"Shell" của chúng ta nhận được một lệnh -c
gọi kiểu, với toàn bộ lệnh là một đối số, giống như cách /bin/sh
sẽ nhận nó.
Vì vậy, như bạn có thể thấy, những gì chúng ta có thể làm bây giờ là phát triển tập lệnh thêm nữa để nó nhận ra trường hợp khi nó được gọi với một -c
đối số, và sau đó phân tích cú pháp chuỗi (giả sử bằng cách so khớp mẫu). Những chuỗi được cho phép có thể được chuyển đến shell thực bằng cách gọi đệ quy /bin/bash -c <string>
. Trường hợp từ chối có thể in thông báo lỗi và kết thúc (bao gồm cả trường hợp khi -c
bị thiếu).
Bạn phải cẩn thận khi viết cái này. Tôi khuyên bạn chỉ nên viết các kết quả phù hợp tích cực chỉ cho phép những thứ rất cụ thể và không cho phép mọi thứ khác.
Lưu ý: nếu đúng như vậy root
, bạn vẫn có thể đăng nhập vào tài khoản này bằng cách ghi đè shell trong su
lệnh, như thế này su -s /bin/bash foo
. (Vỏ thay thế của sự lựa chọn.) Non-root không thể làm điều này.
Đây là một tập lệnh ví dụ: hạn chế người dùng chỉ sử dụng ssh
để git
truy cập vào các kho lưu trữ bên dưới /git
.
#!/bin/sh
if [ $# -ne 2 ] || [ "$1" != "-c" ] ; then
printf "interactive login not permitted\n"
exit 1
fi
set -- $2
if [ $# != 2 ] ; then
printf "wrong number of arguments\n"
exit 1
fi
case "$1" in
( git-upload-pack | git-receive-pack )
;;
( * )
printf "command not allowed\n"
exit 1
;;
esac
gitpath=$(readlink -f "$2")
case "$gitpath" in
( /git/* )
;;
( * )
printf "access denied outside of /git\n"
exit 1
;;
esac
if ! [ -e "$gitpath" ] ; then
printf "that git repo doesn't exist\n"
exit 1
fi
"$1" "$gitpath"
Tất nhiên, chúng tôi tin tưởng rằng các chương trình Git này git-upload-pack
và git-receive-pack
không có lỗ hổng hoặc cửa sập sẽ cho phép người dùng truy cập vào hệ thống.
Đó là điều vốn có trong loại kế hoạch hạn chế này. Người dùng được xác thực để thực thi mã trong một miền bảo mật nhất định và chúng tôi đang đưa ra một hạn chế để giới hạn miền đó ở một miền phụ. Ví dụ: nếu bạn cho phép người dùng chạy vim
lệnh trên một tệp cụ thể để chỉnh sửa nó, người dùng chỉ có thể nhận được một trình bao :!sh[Enter]
.