如何在login后将SSH用户限制在一组预定义的命令中?
这是一个安全的想法。 我们的员工可以访问Linux服务器上的一些命令,但不是全部。 他们应该有可能访问一个日志文件( less logfile
)或启动不同的命令( shutdown.sh
/ run.sh
)。
背景信息:
所有员工使用相同的用户名访问服务器:我们的产品以“正常”用户权限运行,不需要“安装”。 只需将其解压缩到您的用户目录并运行即可。 我们pipe理我们的应用程序“安装”的几个服务器。 在每台机器上都有一个用户johndoe
。 我们的员工有时需要通过命令行访问应用程序来访问和检查日志文件或手动重新启动应用程序。 只有一些人有完整的命令行访问权限。
我们在服务器上使用ppkauthentication。
如果employee1只能访问日志文件,而employee2也可以执行X等,那将是很好的select。
解决scheme:作为解决scheme,我将使用接受的答案中所述的command
选项。 我会自己制作一个小脚本,这将是唯一可以为一些员工执行的文件。 该脚本将提供几个可执行的命令,但不能使用其他命令。 在这里我将使用authorized_keys
的以下参数:
command="/bin/myscript.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-dss AAAAB3....o9M9qz4xqGCqGXoJw= user@host
这对我们来说足够安全。 谢谢,社区!
您还可以将密钥限制为允许的命令(在authorized_keys文件中)。
即用户不会通过SSHlogin,然后有一个有限的命令集,而只能通过SSH执行这些命令(例如“ssh somehost bin / showlogfile”)
ssh
遵循rsh
传统,使用用户的shell程序从密码文件执行命令。
这意味着我们可以通过任何方式解决这个问题而不涉及ssh
configuration。
如果您不希望用户能够访问shell,那么只需用脚本replace该用户的shell即可。 如果你看看/etc/passwd
你会看到有一个域为每个用户分配一个shell命令解释器。 该脚本既用作交互式loginssh user@host
的shell,也用作命令ssh user@host command arg ...
这是一个例子。 我创build了一个用户foo
其shell是一个脚本。 该脚本将输出my arguments are:
后面跟随它的参数(每个在一个单独的行和尖括号中)并终止。 在login的情况下,没有参数。 这是发生了什么事情:
webserver:~# ssh foo@localhost foo@localhost's password: Linux webserver [ snip ] [ snip ] my arguments are: Connection to localhost closed.
如果用户试图运行一个命令,如下所示:
webserver:~# ssh foo@localhost cat /etc/passwd foo@localhost's password: my arguments are: <-c> <cat /etc/passwd>
我们的“shell”接受一个-c
风格的调用,整个命令作为一个参数,就像/bin/sh
接受它的方式一样。
所以,正如你所看到的,我们现在可以做的是进一步开发脚本,以便识别出使用-c
参数调用的情况,然后parsingstring(通过模式匹配)。 那些允许的string可以通过recursion调用/bin/bash -c <string>
传递给真正的shell。 拒绝案例可以打印错误消息并终止(包括-c
丢失的情况)。
你必须小心如何写这个。 我build议只写正面比赛,只允许非常具体的事情,并禁止一切。
注意:如果你是root
,你仍然可以通过在su
命令中重写shell来login到这个帐户,就像su -s /bin/bash foo
。 (替代selectshell)非root不能做到这一点。
下面是一个脚本示例:限制用户只能使用ssh
访问/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 ) ;; # continue execution ( * ) printf "command not allowed\n" exit 1 ;; esac # Canonicalize the path name: we don't want escape out of # git via ../ path components. gitpath=$(readlink -f "$2") # GNU Coreutils specific case "$gitpath" in ( /git/* ) ;; # continue execution ( * ) 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"
当然,我们相信这些Git程序git-upload-pack
和git-receive-pack
没有漏洞或逃生舱口可以让用户访问系统。
这是这种限制scheme所固有的。 用户通过身份validation来执行某个安全域中的代码,并且我们正在克制限制该域到一个子域。 例如,如果您允许用户在特定的文件上运行vim
命令来编辑它,用户可以使用:!sh[Enter]
获得一个shell。
你在找什么叫做Restricted Shell 。 Bash提供了这种模式,用户只能执行主目录中的命令(而不能移动到其他目录),这对你来说可能是足够好的。
我发现这个线程是非常说明性的,如果有点过时。
你应该获得`rssh',这个受限制的shell
你可以按照上面提到的限制指南,它们都是不言自明的,而且简单易懂。 了解“chroot jail”这个术语,以及如何有效地实现sshd /terminalconfiguration等等。
由于大多数用户通过sshd访问terminal,因此您也应该查看sshd_conifg(SSH守护程序configuration文件),以通过SSH应用某些限制。 但是要小心。 正确理解你想要实现的是什么,因为不正确的configuration的分支可能是相当可怕的。
你可能想看看build立一个监狱 。
你为什么不写自己的loginshell? 使用Bash将会非常简单,但是您可以使用任何语言。
在Bash中的示例
使用你最喜欢的编辑器来创build文件/root/rbash.sh
(这可以是任何名称或path,但应该是chown root:root
和chmod 700
):
#!/bin/bash commands=("man" "pwd" "ls" "whoami") timestamp(){ date +'%Y-%m-%s %H:%M:%S'; } log(){ echo -e "$(timestamp)\t$1\t$(whoami)\t$2" > /var/log/rbash.log; } trycmd() { # Provide an option to exit the shell if [[ "$ln" == "exit" ]] || [[ "$ln" == "q" ]] then exit # You can do exact string matching for some alias: elif [[ "$ln" == "help" ]] then echo "Type exit or q to quit." echo "Commands you can use:" echo " help" echo " echo" echo "${commands[@]}" | tr ' ' '\n' | awk '{print " " $0}' # You can use custom regular expression matching: elif [[ "$ln" =~ ^echo\ .*$ ]] then ln="${ln:5}" echo "$ln" # Beware, these double quotes are important to prevent malicious injection # For example, optionally you can log this command log COMMAND "echo $ln" # Or you could even check an array of commands: else ok=false for cmd in "${commands[@]}" do if [[ "$cmd" == "$ln" ]] then ok=true fi done if $ok then $ln else log DENIED "$cmd" fi fi } # Optionally show a friendly welcome-message with instructions since it is a custom shell echo "$(timestamp) Welcome, $(whoami). Type 'help' for information." # Optionally log the login log LOGIN "$@" # Optionally log the logout trap "trap=\"\";log LOGOUT;exit" EXIT # Optionally check for '-c custom_command' arguments passed directly to shell # Then you can also use ssh user@host custom_command, which will execute /root/rbash.sh if [[ "$1" == "-c" ]] then shift trycmd "$@" else while echo -n "> " && read ln do trycmd "$ln" done fi
你所要做的就是将这个可执行文件设置为你的loginshell。 例如,编辑你的/etc/passwd
文件,用/root/rbash.sh
replace你的用户/bin/bash
当前loginshell。
这只是一个简单的例子,但是你可以把它作为先进的,这个想法就在那里。 注意不要通过更改自己和唯一用户的loginshell来locking自己。 总是testing奇怪的符号和命令,看它是否真的安全。
您可以使用以下命令testing它: su -s /root/rbash.sh
。
当心 ,一定要匹配整个命令,并注意通配符! 更好地排除Bash符号,如;
, &
, &&
, ||
, $
,并确定反引号。
根据你给用户的自由,它不会比这更安全。 我发现通常我只需要让一个用户只能访问一些相关的命令,在这种情况下,这真的是更好的解决scheme。 但是,你是否想给更多的自由,监狱和权限可能更合适。 错误很容易做出来,只有在已经太晚的时候才会注意到。
另一种看待这种情况的方法是使用POSIX ACL,它需要你的文件系统支持,但是你可以在Linux上对所有命令进行细化调整,就像你在Windows上有相同的控制一样(只是没有更好的UI )。 链接
另一个要看的是PolicyKit 。
你必须做相当多的search才能使所有的工作,因为这当然不是Linux的实力。
Google是我们的朋友 。 在第一击中:
- 一旦我尝试这个,它的工作: http : //www.onlamp.com/pub/a/bsd/2003/01/23/chroot.html
- http://www.webhostingtalk.com/archive/index.php/t-112326.html
- http://ask.metafilter.com/48951/How-to-restrict-shell-access
- http://www.cyberciti.biz/tips/howto-linux-unix-rssh-chroot-jail-setup.html
HTH