Openssh sftp server, chroot fails to change directory

Hi,

I'm having a problem with openssh running a chroot sftp server. I've followed a couple of guides to the letter, but end up in a situation an sftp client connects, authenticates and then tries to cd $HOMEDIR but fails and disconnects. I ran this exact config on an older dist (a chaos calmer one) which worked fine. Does anyone know what am I missing?

System info

root@lundgw:/etc/ssh# cat /proc/version
Linux version 4.14.131 (buildbot@2ccc8102e0c3) (gcc version 7.3.0 (OpenWrt GCC 7.3.0 r7808-ef686b7292)) #0 SMP Thu Jun 27 12:18:52 2019

root@lundgw:/etc/ssh# sshd -v
sshd: unrecognized option: v
OpenSSH_7.7p1, OpenSSL 1.0.2s  28 May 2019

root@lundgw:/etc/ssh# opkg list-installed|grep openssh
openssh-client - 7.7p1-2
openssh-keygen - 7.7p1-2
openssh-server - 7.7p1-2
openssh-sftp-client - 7.7p1-2
openssh-sftp-server - 7.7p1-2

This is how I set up the user

root@lundgw:/# mkdir jail
root@lundgw:/# chown root:root jail
root@lundgw:/# cd jail
root@lundgw:/jail# mkdir testsftp
root@lundgw:/jail# useradd -U -d /testsftp -s /bin/false testsftp
root@lundgw:/jail# passwd testsftp
root@lundgw:/jail# chown testsftp:testsftp testsftp/
root@lundgw:/jail# chmod 700 testsftp/

This is how I setup the sshd

root@lundgw:/jail# cat /etc/ssh/sshd_config | grep -v -E ^#|grep -v -E ^$
Port 2022
AddressFamily inet
AllowUsers testsftp
LogLevel VERBOSE
PermitRootLogin no
RSAAuthentication yes
UsePrivilegeSeparation sandbox          # Default for new installations.
Subsystem       sftp    internal-sftp
Match User testsftp
        ChrootDirectory /jail/
        X11Forwarding no
        AllowTcpForwarding no
        ForceCommand internal-sftp

This is what the client trying to connect will report

linus@lundgw:~$ sftp -P 2022 testsftp@theserver
testsftp@theserver's password:
Connected to testsftp@theserver.
Couldn't canonicalize: No such file or directory
Need cwd

Or if connecting using winscp I get

Error getting name of current remote directory. Cannot get real path for '.'. No such file or directory

Can't see much in the sshd log, but running on DEBUG3 I can at least see it successfully chroots:

Mon Sep  9 20:14:54 2019 auth.info sshd[20971]: User child is on pid 20973
Mon Sep  9 20:14:54 2019 auth.debug sshd[20973]: debug3: safely_chroot: checking '/'
Mon Sep  9 20:14:54 2019 auth.debug sshd[20973]: debug3: safely_chroot: checking '/jail/'
Mon Sep  9 20:14:54 2019 auth.debug sshd[20973]: debug3: safely_chroot: checking '/jail/'
Mon Sep  9 20:14:54 2019 auth.debug sshd[20971]: debug3: mm_request_receive entering
Mon Sep  9 20:14:54 2019 auth.debug sshd[20971]: debug1: do_cleanup

Tried running strace on the sshd process, but didn't get much smarter, extract below maybe says something to someone?

20984 close(46)                         = -1 EBADF (Bad file descriptor)
....
20984 close(1022)                       = -1 EBADF (Bad file descriptor)
20984 close(1023)                       = -1 EBADF (Bad file descriptor)
20984 chdir("/testsftp")                = 0
20984 getpid()                          = 20984
20984 open("/proc/20984/fd", O_RDONLY|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = -1 ENOENT (No such file or directory)
20984 prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024, rlim_max=4*1024}) = 0
20984 close(3)                          = -1 EBADF (Bad file descriptor)
...
20984 close(1023)                       = -1 EBADF (Bad file descriptor)
20984 stat64("/etc/ssh/sshrc", 0xbeb0bdb0) = -1 ENOENT (No such file or directory)
20984 rt_sigaction(SIGPIPE, NULL, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=0}, 8) = 0
20984 rt_sigaction(SIGPIPE, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0xb6f52d2c}, NULL, 8) = 0
20984 close(-1)                         = -1 EBADF (Bad file descriptor)
20984 close(-1)                         = -1 EBADF (Bad file descriptor)
20984 prctl(PR_SET_DUMPABLE, SUID_DUMP_DISABLE) = 0
20984 _newselect(2, [0], [], NULL, NULL) = 1 (in [0])

If I set ChrootDirectory / it works (but not much of a jail)

Hello

did you find a solution? I have exactly the same problem right now.

To the above mentioned information, I could add that when logging is set-up inside a chroot jail (using syslog-ng and this guide), I have in logs this:

Nov 23 15:58:01 OpenWrt sshd[1956]: Accepted password for test from 192.168.2.175 port 51124 ssh2
Nov 23 15:58:01 OpenWrt internal-sftp[1960]: session opened for local user test                      from [192.168.2.175]
Nov 23 15:58:01 OpenWrt internal-sftp[1960]: received client version 3
Nov 23 15:58:01 OpenWrt internal-sftp[1960]: debug3: request 256: realpath
Nov 23 15:58:01 OpenWrt internal-sftp[1960]: realpath "."
Nov 23 15:58:01 OpenWrt internal-sftp[1960]: debug3: request 256: sent status 2
Nov 23 15:58:01 OpenWrt internal-sftp[1960]: sent status No such file

It seems that the problem is WRT cannot get realpath for "." inside chroot jail. Any ideas what to do with that?

Bump. Anyone?

opkg install coreutils-realpath
||
CONFIG_BUSYBOX_DEFAULT_REALPATH

With coreutils-realpath still similar result, log:


Nov 29 10:06:12 OpenWrt sshd[12553]: Accepted password for test from 192.168.2.175 port 61107 ssh2
Nov 29 10:06:12 OpenWrt internal-sftp[12557]: session opened for local user test from [192.168.2.175]
Nov 29 10:06:12 OpenWrt internal-sftp[12557]: received client version 6
Nov 29 10:06:12 OpenWrt internal-sftp[12557]: debug3: request 43536: realpath
Nov 29 10:06:12 OpenWrt internal-sftp[12557]: realpath "/"
Nov 29 10:06:12 OpenWrt internal-sftp[12557]: debug3: request 43536: sent status 2
Nov 29 10:06:12 OpenWrt internal-sftp[12557]: sent status No such file
Nov 29 10:06:22 OpenWrt internal-sftp[12557]: debug3: request 43792: realpath
Nov 29 10:06:22 OpenWrt internal-sftp[12557]: realpath "."
Nov 29 10:06:22 OpenWrt internal-sftp[12557]: debug3: request 43792: sent status 2
Nov 29 10:06:22 OpenWrt internal-sftp[12557]: sent status No such file
Nov 29 10:06:23 OpenWrt internal-sftp[12557]: debug3: request 44048: realpath
Nov 29 10:06:23 OpenWrt internal-sftp[12557]: realpath "."
Nov 29 10:06:23 OpenWrt internal-sftp[12557]: debug3: request 44048: sent status 2
Nov 29 10:06:23 OpenWrt internal-sftp[12557]: sent status No such file
Nov 29 10:06:25 OpenWrt internal-sftp[12557]: debug3: request 44304: realpath
Nov 29 10:06:25 OpenWrt internal-sftp[12557]: realpath "."
Nov 29 10:06:25 OpenWrt internal-sftp[12557]: debug3: request 44304: sent status 2
Nov 29 10:06:25 OpenWrt internal-sftp[12557]: sent status No such file
Nov 29 10:06:26 OpenWrt internal-sftp[12557]: debug3: request 44555: opendir
Nov 29 10:06:26 OpenWrt internal-sftp[12557]: opendir ""
Nov 29 10:06:26 OpenWrt internal-sftp[12557]: debug3: request 44555: sent status 2
Nov 29 10:06:26 OpenWrt internal-sftp[12557]: sent status No such file
Nov 29 10:06:26 OpenWrt internal-sftp[12557]: debug3: request 44816: realpath
Nov 29 10:06:26 OpenWrt internal-sftp[12557]: realpath "."
Nov 29 10:06:26 OpenWrt internal-sftp[12557]: debug3: request 44816: sent status 2
Nov 29 10:06:26 OpenWrt internal-sftp[12557]: sent status No such file
Nov 29 10:06:26 OpenWrt internal-sftp[12557]: debug3: request 45072: realpath
Nov 29 10:06:26 OpenWrt internal-sftp[12557]: realpath "."
Nov 29 10:06:26 OpenWrt internal-sftp[12557]: debug3: request 45072: sent status 2
Nov 29 10:06:26 OpenWrt internal-sftp[12557]: sent status No such file
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: debug3: request 45328: realpath
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: realpath "."
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: debug3: request 45328: sent status 2
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: sent status No such file
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: debug3: request 45584: realpath
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: realpath "."
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: debug3: request 45584: sent status 2
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: sent status No such file
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: debug3: request 45840: realpath
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: realpath "."
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: debug3: request 45840: sent status 2
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: sent status No such file
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: debug3: request 46096: realpath
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: realpath "."
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: debug3: request 46096: sent status 2
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: sent status No such file
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: debug3: request 46352: realpath
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: realpath "."
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: debug3: request 46352: sent status 2
Nov 29 10:06:27 OpenWrt internal-sftp[12557]: sent status No such file

thought so... you can try with busybox but i suspect the result will be the same...

there was a comment recently on the mailing list / pr's re: busybox suid handling or similar ... which is "possibly" related... / touch on one subsystem involved...

but... when I messed around recently with this...

like you most all tracing is fine up until it switches to the "chrooted" environment... the few path hacks I tried seemed non-responsive to anything outside of standard file paths... ( in other words... i'm confident i tested enough to rule out config issues )

from memory.... i dropped what I was doing but it had something to do with some "realpath c code" mods... i think in the sftp? source....then again... it probably wasn't... maybe in one the "package/source bundles" that provided the realpath function... ( which some other internet links seems to hint might be responsible.... )

that's about where my interest and skill level got the best of me... ( was purely a learning endeavor as I have no need in particular for this ) but if you keep at it... i'd exclude the suid business / any other "core capabilities" that are "compiled out" first.... ( which includes common "multiuser" type packages )

Unfortunately that is far beyond my skills :frowning: All I could was that I've tested many combinations of file permissions/home dirs/chroot jails, without any success.

Musl libc realpath() requires access to /proc/self/fd/ to function. You need to ensure that this directory is available in the chroot, e.g. by bind-mounting it.

2 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.