Trouble Removing Files In Chrooted Sftp

Home » CentOS » Trouble Removing Files In Chrooted Sftp
CentOS 3 Comments

Hi,

I have trouble setting up chrooted SFTP for our user. I got the basic SFTP chroot working, user is chrooted to its home directory, I’ve added /home/userb/etc directory with dummy passwd, group and localtime files.

The problem is that instead of only accessing its own files, I need the user to be able to remove another users files. I have web application which runs as different user, the sftp user is member of the web users group. I then setup bind mounts from web users data dir to chrooted users home directory.

The chrooted user can’t remove any files in the directory owned by another user. The directory permissions are 0775 so they should allow the access. If I don’t use chroot I can remove the file just fine so it seems to be something on the chroot that limits the access.

I tried to add simple directory, checked the permissions and tried to delete file and it failed as well so the bind mount should be the issue.

Here’s sample output:
# cat etc/{passwd,group}
webapp-user:x:5020:5020::/home/webapp-user:/sbin/nologin chroot-user:x:5029:10000::/home/chroot-user:/sbin/nologin root:x:0:0:not really root:::
sftp-chroot:x:10000:chroot-user webapp-user:x:5020:chroot-user
# ls -lR
.:
total 0
drwx–x— 2 root sftp-chroot 61 Jan 5 07:34 etc drwxr-x— 2 chroot-user sftp-chroot 6 Nov 20 2015 failed drwxr-x— 2 chroot-user sftp-chroot 16 Jan 5 07:46 input drwxrwxr-x 2 webapp-user webapp-user 98 Jan 5 07:18 intranet

./etc:
total 16
-rw-r–r– 1 root root 55 Jan 5 07:34 group
-rw-r—– 1 root root 1883 Jan 5 06:45 localtime
-rw-r–r– 1 root root 172 Jan 5 06:51 passwd
-rw-r–r– 1 root root 105 Jan 5 06:46 passwd~

./failed:
total 0

./input:
total 0

./intranet:
total 72
-rw-rw-r– 1 chroot-user sftp-chroot 0 Jan 5 07:02 test1.txt
-rw-rw-r– 1 webapp-user webapp-user 0 Jan 5 07:02 test2.txt

So why can’t I remove the intranet/test* files inside sftp chroot even if the chroot-user is member of webapp-user group and the directory itself has group permissions?

Br, Timo M

3 thoughts on - Trouble Removing Files In Chrooted Sftp

  • I just did a bit of testing on OpenBSD and there the above setup seems to work and I can remove the files just fine over sftp. So this thing should work but there’s still something causing it to fail on CentOS’s side. One difference between our CentOS and OpenBSD is that OpenBSD uses newer openssh server. I looked through the release notes and didn’t see any changes related to internal-sftp.

    I fixed the /home/chroot-user/etc/localtime permissions to 0644 and run strace on internal-sftp process and got following output:

    read(0, “\0\0\0\23\v\0\0\0009\0\0\0\n/intranet/”, 16384) = 23
    openat(AT_FDCWD, “/intranet/”, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) =
    3
    select(2, [0], [1], NULL, NULL) = 1 (out [1])
    write(1, “\0\0\0\rf\0\0\0009\0\0\0\4\0\0\0\0”, 17) = 17
    select(2, [0], [], NULL, NULL) = 1 (in [0])
    read(0, “\0\0\0\r\f\0\0\0:\0\0\0\4\0\0\0\0”, 16384) = 17
    getdents(3, /* 7 entries */, 32768) = 216
    lstat(“/intranet//.”, {st_mode=S_IFDIR|0775, st_size=98, …}) = 0
    stat(“/etc/localtime”, {st_mode=S_IFREG|0644, st_size=1883, …}) = 0
    lstat(“/intranet//..”, {st_mode=S_IFDIR|0755, st_size=56, …}) = 0
    stat(“/etc/localtime”, {st_mode=S_IFREG|0644, st_size=1883, …}) = 0
    lstat(“/intranet//120007f.dotx”, {st_mode=S_IFREG|0664, st_size=63788,
    …}) = 0
    stat(“/etc/localtime”, {st_mode=S_IFREG|0644, st_size=1883, …}) = 0
    lstat(“/intranet//120007f.xml.orig”, {st_mode=S_IFREG|0640, st_size=607,
    …}) = 0
    stat(“/etc/localtime”, {st_mode=S_IFREG|0644, st_size=1883, …}) = 0
    lstat(“/intranet//120007f.xml”, {st_mode=S_IFREG|0664, st_size=607, …}) =
    0
    stat(“/etc/localtime”, {st_mode=S_IFREG|0644, st_size=1883, …}) = 0
    lstat(“/intranet//test1.txt”, {st_mode=S_IFREG|0664, st_size=0, …}) = 0
    stat(“/etc/localtime”, {st_mode=S_IFREG|0644, st_size=1883, …}) = 0
    lstat(“/intranet//test2.txt”, {st_mode=S_IFREG|0664, st_size=0, …}) = 0
    stat(“/etc/localtime”, {st_mode=S_IFREG|0644, st_size=1883, …}) = 0
    getdents(3, /* 0 entries */, 32768) = 0
    select(2, [0], [1], NULL, NULL) = 1 (out [1])
    write(1, “\0\0\3/h\0\0\0:\0\0\0\7\0\0\0\1.\0\0\0;drwxrwxr-x”…, 819) = 819
    select(2, [0], [], NULL, NULL) = 1 (in [0])
    read(0, “\0\0\0\r\f\0\0\0;\0\0\0\4\0\0\0\0”, 16384) = 17
    getdents(3, /* 0 entries */, 32768) = 0
    select(2, [0], [1], NULL, NULL) = 1 (out [1])
    write(1, “\0\0\0\34e\0\0\0;\0\0\0\1\0\0\0\vEnd of file\0\0\0\0”, 32) = 32
    select(2, [0], [], NULL, NULL) = 1 (in [0])
    read(0, “\0\0\0\r\4\0\0\0<\0\0\0\4\0\0\0\0", 16384) = 17 close(3) = 0 select(2, [0], [1], NULL, NULL) = 1 (out [1]) write(1, "\0\0\0\30e\0\0\0<\0\0\0\0\0\0\0\7Success\0\0\0\0", 28) = 28 select(2, [0], [], NULL, NULL) = 1 (in [0]) read(0, "\0\0\0\34\7\0\0\0=\0\0\0\23/intranet/test2.txt", 16384) = 32 lstat("/intranet/test2.txt", {st_mode=S_IFREG|0664, st_size=0, ...}) = 0 select(2, [0], [1], NULL, NULL) = 1 (out [1]) write(1, "\0\0\0%i\0\0\0=\0\0\0\17\0\0\0\0\0\0\0\0\0\0\23\234\0\0\23\234\0\0\201"..., 41) = 41 select(2, [0], [], NULL, NULL) = 1 (in [0]) read(0, "\0\0\0\34\7\0\0\0>\0\0\0\23/intranet/test2.txt”, 16384) = 32
    lstat(“/intranet/test2.txt”, {st_mode=S_IFREG|0664, st_size=0, …}) = 0
    select(2, [0], [1], NULL, NULL) = 1 (out [1])
    write(1,
    “\0\0\0%i\0\0\0>\0\0\0\17\0\0\0\0\0\0\0\0\0\0\23\234\0\0\23\234\0\0\201″…,
    41) = 41
    select(2, [0], [], NULL, NULL) = 1 (in [0])
    read(0, “\0\0\0\34\r\0\0\0?\0\0\0\23/intranet/test2.txt”, 16384) = 32
    unlink(“/intranet/test2.txt”) = -1 EACCES (Permission denied)
    select(2, [0], [1], NULL, NULL) = 1 (out [1])
    write(1, “\0\0\0\”e\0\0\0?\0\0\0\3\0\0\0\21Permission deni”…, 38) = 38
    select(2, [0], [], NULL, NULL

    The relevant sections are probably:
    stat(“/intranet//.”, {st_mode=S_IFDIR|0775, st_size=98, …}) = 0
    … unlink(“/intranet/test2.txt”) = -1 EACCES (Permission denied)

    So the /intranet has 0775 permissions which should allow chroot-user to remove files if it belongs to web-user group. Removal works outside chroot.

    How can I verify which groups the user has in sftp chroot?

    Timo

    2017-01-09 12:31 GMT+02:00 Myyrä, Timo :


    Parhain terveisin,

    Timo Myyrä
    Palvelinylläpitäjä
    Edita Prima Oy, Kehitysyksikkö
    Vilhonvuorenkatu 12
    PL 510
    00043 NORDIC MORNING
    +358 40 860 2103
    timo.myyra@edita.fi

  • Hi

    Just as a question is SELinux enabled ?

    ]# getenforce Enforcing

    I would assume so. As a test you could try turning this off and see if your problem goes away.

    setenforce 0

    If SELinux is the issue then I strongly advice that you use existing SELinux Booleans or create your own local policy rather than turning SELinux off, or leaving your system in permissive mode.

    # getsebool -a | grep chroot

    ssh_chroot_full_access –> off ssh_chroot_manage_apache_content –> off ssh_chroot_rw_homedirs –> off

    https://wiki.CentOS.org/HowTos/SELinux may also help.

    If it is SELinux related I would also look at installing setroubleshoot and setroubleshoot-server.

    I hope this helps :)

  • Ah, forgot to mention that the SELinux is not enabled on this server. So thats not causing this.

    Timo

    2017-01-11 22:23 GMT+02:00 Clint Dilks :


    Parhain terveisin,

    Timo Myyrä
    Palvelinylläpitäjä
    Edita Prima Oy, Kehitysyksikkö
    Vilhonvuorenkatu 12
    PL 510
    00043 NORDIC MORNING
    +358 40 860 2103
    timo.myyra@edita.fi