i have an account that can ssh to localhost alright:

$ ssh root@localhost
# logout
Connection to localhost closed.

it does not work with the JumpProxy feature of ssh however:

$ ssh -J root@localhost root@localhost
/sbin/nologin: invalid option -- 'c'

 nologin [options]

Politely refuse a login.

 -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

This seems to be related to the fact that the shell of the current user is set to /sbin/nologin -- if I temporarily change it to bash the command works. it appears to be best practice to disable shell access for users that do not need it -- but (why???) does JumpProxy need it?

  • 1
    Possible dup - unix.stackexchange.com/questions/184031/…
    – slm
    Jul 21 '18 at 19:55
  • no duplicate imho. the remote user is root and thus not a nologin user. the local user is a nologin user and I do not understand why this would influence the situation.
    – mnagel
    Jul 22 '18 at 8:39

In my testing on OpenSSH 7.4, specifically:

$ ssh -V
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017

I was able to set my user's shell to either /sbin/nologin or /bin/false and was able to log into server B through server A.


$ cat /etc/passwd


$ cat /etc/passwd
host A → B

Tries to log into server B (mulder) through server A (centos7) worked.

[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 ~]#
host A → B → C

And on the off chance that it was something funny with my going through the VM, I added a 3rd host to the mix, and it still worked.

[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
[root@skinner ~]# 

NOTE: in the above scenario, the user1 has /sbin/nologin defined in /etc/passwd on the servers centos7 & mulder.

Debugging your issue

So I'd start with -vvv switches to debug 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
[root@skinner ~]#

NOTE: With the above you can see what -J is actually doing behind the scenes, as it expands to various ssh commands as it progresses through the jump proxy servers.

To triage your issue further, I'd suggest running these commands directly and seeing how they fare.

root@localhost → root@localhost

In my experiments I could ssh in the same manner that you were trying:

$ 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

To do this you have to have /etc/ssh/sshd_config set so that root is permitted logging in.


  • thanks for the thorough analysis. note that in [vagrant@centos7 ~]$ ssh -J user1@localhost root@mulder i did something different. for me vagrant (!) would be the no login user and instead of user1 I used root who can login. i.e. my situation is that the local user is a nologin user and all the users on the proxy and the destination are normal users. for some reason SSH wants to run a shell LOCALLY as the user initiating the ssh session if there are proxies in between.
    – mnagel
    Jul 22 '18 at 8:45
  • @mnagel - I did testing as well where my user1 locally was nologin, made no difference, it still worked.
    – slm
    Jul 22 '18 at 8:47
  • Did you somehow have the environment variable SHELL set when you ran all these tests. I think that would have made this work despite changing the user's shell. See my answer below for more details.
    – Jarryd
    Jan 22 '19 at 23:59
  • @Jarryd - likely. $SHELL is always set in distros I've used. I can't think of a instance where it wasn't.
    – slm
    Jan 24 '19 at 13:23
  • Actually I'm not sure that you're testing the right thing. Does your vagrant user where you start this from have /usr/sbin/nologin?
    – Jarryd
    Jan 25 '19 at 0:48

In the manpage of ssh_config for ProxyCommand, it says

The command string extends to the end of the line, and is executed using the user's shell ‘exec’ directive to avoid a lingering shell process.

I ran this with strace and saw the following:

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 ...>

Basically I think SSH is trying to be clever and looking up the user's shell and then running the proxy command using the shell. But when the shell doesn't exist it fails.

If you set the environment variable SHELL before you run ssh then it will fix the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.