我目前在使用 LDAP 进行身份验证的网络中工作。设置zsh
为我的登录 shell 后,我遇到了通过网络上的一台计算机进行远程访问的问题,ssh
而该计算机显然尚未zsh
安装。登录失败并显示
Dec 8 19:16:11 abert sshd[20649]: User sorokine not allowed because shell /bin/zsh does not exist
所以问题基本上是:如何告诉远程计算机使用与 LDAP 中配置的登录 shell 不同的登录 shell?
OpenSSH_6.0p1 Debian-4+deb7u2、OpenSSL 1.0.1e
答案1
如果您的登录 shell 无法在某些机器上执行,那么您就无法通过 SSH 或大多数其他方法登录到该机器。 SSH 服务器始终执行您的登录 shell。如果您在命令行上传递命令,则登录 shell将以命令字符串 1 作为参数ssh
执行;-c
否则,登录 shell 将作为不带参数的登录 shell 执行。
如果有办法绕过登录 shell,那将是一个安全漏洞。可以通过将帐户的登录外壳设置为仅执行一项特定任务的程序来将帐户配置为受限帐户;例如,登录 shell 可以是git-shell
只允许访问 git 存储库,或者rssh
, ETC。
要登录到该计算机,您需要安排/bin/zsh
在场,或者将您的登录 shell 更改为在场。
在这样的异构环境中,我建议坚持/bin/sh
使用登录 shell,因为它无处不在。将环境变量设置SHELL
为/bin/zsh
(如果存在),这样您就可以将 zsh 作为交互式 shell。
if [ -x /bin/zsh ]; then
export SHELL=/bin/zsh
fi
当您这样做时,这可以让您避免硬编码zsh
.
if SHELL=$(command -v zsh); then
export SHELL
else
unset SHELL
fi
要让 zsh 自动运行以进行文本模式登录,请从您的.profile
.如果您想使用.zprofile
它来进行设置,请将其设置为登录 shell(但是在不存在 zsh 的计算机上您将无法获得相同的环境,因此我不建议这样做)。仅当这是交互式登录时才执行此操作,而不是在.profile
由脚本执行时、在 GUI 模式登录等期间执行此操作。
if case $- in *i*) true;; *) false;; esac && # interactive shell
[ -z "$ZSH_VERSION" ] && # not running zsh yet
type zsh >/dev/null 2>/dev/null; then # zsh is present
exec zsh
fi
1 SSH 客户端将其非选项参数与中间的空格连接起来,并通过连接发送结果字符串。 SSH 协议将命令定义为字符串,而不是字符串列表。
答案2
如果您可以通过其他方式访问,则必须在指定计算机上安装 shell,或者请求管理员为您执行此操作,或者将 ldap 中的 shell 更改为远程计算机上存在的 shell。
(打开)sshd 将总是检查用户 shell,它会总是执行该 shell 传递给执行的任何内容。如果传递另一个 shell 来执行,它将执行它,并将其作为参数传递给用户 shell,例如用户 shell 是“/bin/sh”,并且您将 csh shell 作为参数传递,它将运行“/bin/ sh -c /bin/csh'。