Why can /bin/false do port forwarding with ssh's -NL option even in the login shell?

Asked 2 years ago, Updated 2 years ago, 81 views

As the title suggests, why can /bin/false do port forwarding with the -NL option in the login shell?
When I tried, /sbin/nologin could not do port forwarding.

When I looked it up myself, I understood that if I added it to /etc/shells, I could use FTP, but I didn't add /bin/false or or to /etc/shells.I would appreciate it if you could teach me.Thank you for your cooperation.

The server environment is Debian 7.10, and the sshd version is OpenSSH_6.0p1 Debian-4+deb7u4, OpenSSL 1.0.1e11 Feb 2013.
The client ssh version is OpenSSH_6.9p1, LibreSSL 2.1.8.

ssh

2022-09-30 19:53

2 Answers

This is because the SSH server sshd(8) checks for the user's shell and rejects it if it does not exist.Debian should check /var/log/auth.log for authentication behavior.I think the following logs are available:

 Apr 30 19:07:17 sugar sshd [13663]: User fumiyas not allowed cause shell/sbin/nologin does not exist

sshd only checks if the file exists and has owner, ownership group, or other execution privileges, so SSH port transfers are permitted, for example:

#touch/sbin/nologin
# chmod0100/sbin/nologin

Debian/Ubuntu does not have /sbin/nologin, but /usr/sbin/nologin exists and has execution privileges, so you can specify it in the shell to transfer ports.

sshd itself does not evaluate shells(5).If necessary, set UsePAM yes in sshd_config (5) and use pam_shells (8) in pam.conf (5).


2022-09-30 19:53

For your information, port forwarding may be possible even if the login shell does not exist or you do not have permission to execute, so I will write a little bit about that.

The execution environment is as follows:

OS: Linux 4.4.0
Distro: Ubuntu 16.04
  sshd —OpenSSH 7.2p2

openssh-7.2p2/auth.c

int
allowed_user(struct passwd*pw)
{
              :
  /*
   * Deny if shell does not exist or is not executable unless we
   * are chrooting.
   */
  if(options.chroot_directory==NULL||
      strcasecmp(options.chroot_directory, "none")==0){
    char*shell=xstrdup(pw->pw_shell[0]=='\0') ?
        _PATH_BSHELL: pw->pw_shell);/*empty=/bin/sh*/

    if(stat(shell, & st)!=0){
      logit("User%.100s not allowed cause shell%.100s"
          "does not exist", pw->pw_name, shell);
                   :

The above section examines the contents of options.chroot_directory, which is equivalent to ChrootDirectory in the sshd_config file.

srv$ls-l/sbin/nologin
ls:cannot access '/sbin/nologin'—No such file or directory
srv$sudochsh-s/sbin/nologinemo
chsh —Warning: /sbin/nologin does not exist
srv$getent passwd nemo
nemo:x:1001:100:testing:/nonexistent:/sbin/nologin

Perform (local) port forwarding from the client side to the server (IP address: 192.168.0.3) side.

cli$ssh-fNL10000:127.0.0.1:[email protected]
[email protected]'s password: 
Permission denied, please try again.
            :
Permission denied (publickey, password). 

Now that it has failed, add the ChrootDirectory setting to the server side /etc/ssh/sshd_config and

/etc/ssh/sshd_config

Match Usernemo
  ChrootDirectory/chroot

Restart sshd.

 srv$ls-ld/chroot
drwxr-xr-x2 root root 4096/chroot/
srv$ sudo service sshd restart 

Try port forwarding again.

cli$ssh-fNL10000:127.0.0.1:[email protected]
[email protected]'s password: 

Access port 10000 on the client.

cli$telnet localhost10000
Trying 127.0.0.1...
Connected to localhost.
Escape character is'^]'.

You can also port forwarding if the login shell is not configured, as you can read from the previous source code.

_PATH_BSHELL:pw->pw_shell);/*empty=/bin/sh*/

As stated in this comment, the login shell is /bin/sh and the process continues.

 srv$sudo chsh-s'"nemo
chsh:Warning: does not exist
srv$getent passwd nemo
nemo:x:1001:100:testing:/nonexistent:

Removing the ChrootDirectory configuration in sshd_config and restarting sshd, you can try port forwarding.

Regardless of setting ChrootDirectory, it is difficult to assume that the login shell setting is empty, but I think it is better to consider it.

"However, if the intention of the question is ""I want to control the availability of port forwarding by user,"" there is also a way to use the ""code>Match User" mentioned earlier."

/etc/ssh/sshd_config

Match Usernemo
  AllowTcpForwarding no

Set the login shell to /bin/false and perform port forwarding.

$ls-l/bin/false
-rwxr-xr-x1 root root root26364/bin/false
srv$sudo chsh-s/bin/false nemo
srv$getent passwd nemo
nemo:x:1001:100:testing:/nonexistent:/bin/false

cli$ssh-fNL10000:localhost:[email protected]
[email protected]'s password: 
cli$telnet localhost10000
Trying 127.0.0.1...
Connected to localhost.
channel1: open failed:administratively prohibited:open failed
Escape character is'^]'.
Connection closed by foreign host.


2022-09-30 19:53

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.