我有一个可以 ssh 到本地主机的帐户:
$ ssh root@localhost
# logout
Connection to localhost closed.
但是它不能与 ssh 的 JumpProxy 功能一起使用:
$ ssh -J root@localhost root@localhost
/sbin/nologin: invalid option -- 'c'
Usage:
nologin [options]
Politely refuse a login.
Options:
-h, --help display this help and exit
-V, --version output version information and exit
For more details see nologin(8).
ssh_exchange_identification: Connection closed by remote host
这似乎与当前用户的 shell 设置为 /sbin/nologin 有关——如果我临时将其更改为 bash,该命令就可以工作。对不需要的用户禁用 shell 访问似乎是最佳实践——但是(为什么???)JumpProxy 需要它吗?
答案1
在我对 OpenSSH 7.4 的测试中,具体来说:
$ ssh -V
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017
我能够将用户的 shell 设置为 或 ,/sbin/nologin
并且/bin/false
能够通过服务器 A 登录到服务器 B。
例子
$ cat /etc/passwd
user1:x:1001:1001::/home/user1:/sbin/nologin
或者
$ cat /etc/passwd
user1:x:1001:1001::/home/user1:/bin/false
主机A→B
尝试通过服务器A(centos7)登录服务器B(mulder)成功。
[vagrant@centos7 ~]$ ssh -J user1@localhost root@mulder
user1@localhost's password:
Last login: Sat Jul 21 15:59:00 2018 from macbook1
[root@mulder ~]#
主机A→B→C
如果我在虚拟机中遇到一些有趣的事情,我添加了第三台主机,它仍然有效。
[vagrant@centos7 ~]$ ssh -J user1@localhost,user1@mulder root@skinner
user1@localhost's password:
user1@mulder's password:
Last login: Sat Jul 21 16:09:48 2018 from 192.168.1.10
[root@skinner ~]#
笔记:在上述场景中,user1 已在服务器 centos7 和 mulder 上/sbin/nologin
定义。/etc/passwd
调试您的问题
所以我会从-vvv
开关开始调试ssh
。
$ ssh -vvv -J user1@localhost,user1@mulder root@skinner
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 58: Applying options for *
debug1: Setting implicit ProxyCommand from ProxyJump: ssh -l user1 -J user1@localhost -vvv -W %h:%p mulder
debug1: Executing proxy command: exec ssh -l user1 -J user1@localhost -vvv -W skinner:22 mulder
...
...
debug1: Setting implicit ProxyCommand from ProxyJump: ssh -l user1 -vvv -W %h:%p localhost
debug1: Executing proxy command: exec ssh -l user1 -vvv -W mulder:22 localhost
...
...
debug2: PTY allocation request accepted on channel 0
debug2: channel 0: rcvd adjust 2097152
debug3: receive packet: type 99
debug2: channel_input_status_confirm: type 99 id 0
debug2: shell request accepted on channel 0
Last login: Sat Jul 21 16:10:28 2018 from 192.168.1.10
[root@skinner ~]#
笔记:通过上面的内容,您可以看到-J
幕后实际执行的操作,因为它ssh
在通过跳转代理服务器时扩展为各种命令。
为了进一步分类您的问题,我建议直接运行这些命令并查看它们的表现。
根@本地主机 → 根@本地主机
在我的实验中,我可以以ssh
与您尝试相同的方式:
$ ssh -J root@localhost root@localhost
root@localhost's password:
root@localhost's password:
Last login: Sat Jul 21 16:40:54 2018 from localhost
CentOS 7 Build 1805.02
$
为此,您必须进行/etc/ssh/sshd_config
设置,以便允许 root 登录。
参考
答案2
ssh_config
在for的联机帮助页中ProxyCommand
,它说
命令字符串延伸到行尾,并使用用户的 shell 'exec' 指令执行以避免 shell 进程延迟。
我运行它strace
并看到以下内容:
write(2, "debug1: Executing proxy command:"..., 114debug1: Executing proxy command: exec ssh -l rundeck -v -W '[target]:22' proxy
[pid 30151] execve("/usr/sbin/nologin", ["/usr/sbin/nologin", "-c", "exec ssh -l rundeck -v -W '[172."...], 0x55f477e50ab0 /* 15 vars */ <unfinished ...>
基本上我认为 SSH 试图变得聪明并查找用户的 shell,然后使用 shell 运行代理命令。但是当 shell 不存在时,它就会失败。
SHELL
如果您在运行之前设置环境变量ssh
,那么问题就会得到解决。