SFTP Chroot
lattera
lattera at gmail.com
Wed Nov 18 13:30:13 EST 2009
Hi all,
Today, I was tasked at work with setting up a chroot SFTP server on a 64bit
Arch Linux server. I naturally turned to Arch Linux's wiki article on the
subject (http://wiki.archlinux.org/index.php/SFTP-chroot) and the directions
were very clear. However, the directions did not work. I kept getting a
"Write failed: Broken pipe" error after attempting to connect. Upon digging
through the code for OpenSSH 5.3p1 , I found this snippet of code, starting
at line 1399 of session.c and ending at line 1452:
/*
> * Chroot into a directory after checking it for safety: all path
> components
> * must be root-owned directories with strict permissions.
> */
> static void
> safely_chroot(const char *path, uid_t uid)
> {
> const char *cp;
> char component[MAXPATHLEN];
> struct stat st;
>
> if (*path != '/')
> fatal("chroot path does not begin at root");
> if (strlen(path) >= sizeof(component))
> fatal("chroot path too long");
>
> /*
> * Descend the path, checking that each component is a
> * root-owned directory with strict permissions.
> */
> for (cp = path; cp != NULL;) {
> if ((cp = strchr(cp, '/')) == NULL)
> strlcpy(component, path, sizeof(component));
> else {
> cp++;
> memcpy(component, path, cp - path);
> component[cp - path] = '\0';
> }
>
> debug3("%s: checking '%s'", __func__, component);
>
> if (stat(component, &st) != 0)
> fatal("%s: stat(\"%s\"): %s", __func__,
> component, strerror(errno));
> if (st.st_uid != 0 || (st.st_mode & 022) != 0)
> fatal("bad ownership or modes for chroot "
> "directory %s\"%s\"",
> cp == NULL ? "" : "component ", component);
> if (!S_ISDIR(st.st_mode))
> fatal("chroot path %s\"%s\" is not a directory",
> cp == NULL ? "" : "component ", component);
>
> }
>
> if (chdir(path) == -1)
> fatal("Unable to chdir to chroot path \"%s\": "
> "%s", path, strerror(errno));
> if (chroot(path) == -1)
> fatal("chroot(\"%s\"): %s", path, strerror(errno));
> if (chdir("/") == -1)
> fatal("%s: chdir(/) after chroot: %s",
> __func__, strerror(errno));
> verbose("Changed root directory to \"%s\"", path);
> }
>
Why should all the directory tree be root-owned and have that set of
permissions? This is preventing me from setting the chroot to /home/<user>
and be done with it, like that wiki article suggests. If there is no
security concern, I would like to remove the offending code (the for loop).
I will probably do this anyways for the project I'm working on, but I am
unsure if the public as a whole could benefit from such a change.
Thanks for taking the time to respond,
Shawn
More information about the openssh-unix-dev
mailing list