How to chroot sftp (and only sftp) :
1. download openssh
2. extract openssh
> tar -xzf openssh-3.0.2p1.tar.gz
> cd openssh-3.0.2p1
3. Configure openssh. I personally only change the sftp-server binary if there is another ssh server installed. For doing this, you must configure the source like the original installation. Otherwise, configure with defaults, or the way you desire. Below is the configure command for redhar 7.1, 7.2
> ./configure --prefix=/usr --libexecdir=/usr/libexec/openssh --sysconfdir=/etc/ssh --mandir=/usr/share/man
4. Patch sftp-server.c with the chroot diff :
> patch make
6. If you install the new source in full, just run make install. otherwise, just replace sftp-server :
find where the original sftp-server is. in my case, it's /usr/libexec/openssh/sftp-server
> locate sftp-server
backup the file, and put our sftp-server instead :
> mv /usr/libexec/openssh/sftp-server /usr/libexec/openssh/sftp-server.old
> cp sftp-server /usr/libexec/openssh/sftp-server
7. make sftp-server GID root :
> chmod +s /usr/libexec/openssh/sftp-server
8. compile and install sftpsh.c : looks like this :
/*
* sftpsh - Secure Shell File Transfer Protocol Shell
*
* This "shell" is to be used to restrict a user's usage of
* SSH to SFTP access only. By setting the user's shell to
* /path/to/sftpsh the SSH server will allow the user access
* to SFTP services without interactive login access.
*
* This software is released under no license or guarantee.
* Use at your own risk.
*
*
* 31 MAY 2001 - Jason A. Dour
*/
/*
* USER-DEFINED VALUES
*
* Define the path to the SFTP Server binary, the execution
* command name of the server, and any command arguments.
* With openssh these values are generally '/path/to/sftp-server,'
* 'sftp-server,' and '' respectively.
*
* Lastly, define the message that is written to stdout when
* an interactive shell is attempted.
*/
#define SFTP_BINARY "/usr/libexec/openssh/sftp-server"
#define SFTP_EXNAME "/usr/libexec/openssh/sftp-server"
#define SFTP_ARGS ""
#define DENY_MESG "\n\rYou do not have interactive login access to this machine.\n\r\n\rContact the system administrator should this not be the case.\n\r"
/*
* DO NOT MODIFY BEYOND THIS POINT UNLESS YOU ARE CERTAIN YOU
* WILL NOT OPEN UP THE SHELL TO ALLOW ANYTHING OTHER THAN THE
* SFTP SERVER TO EXECUTE.
*/
#include
#include
#include
/*
* Output the error and return.
*/
void error(char *program, char *why) {
char *outputstr;
if ( strlen(program) )
outputstr = "%s: %s\n\r";
else
outputstr = "%s%s\n\n";
if ( isatty( fileno(stderr) ) ) {
fprintf(stderr, outputstr, program, why);
return;
} else {
fprintf(stdout, outputstr, program, why);
return;
}
}
/*
* There isn't much to this program. Grab the shell's name.
* Check the argument passed. Either execute or error out.
*/
int main(int argc, char **argv) {
char *progname; /* The sftpsh execution name. */
char *sftp_cmd[] = { /* The SFTP Server command array. */
SFTP_EXNAME,
SFTP_ARGS,
NULL
};
/* Grab the sftpsh execution name. */
if ( strchr(argv[0], '/') )
progname = strrchr(argv[0], '/') + 1;
else
progname = argv[0];
/* Check the of args. Error out if bad. */
if ( ( (argc == 3) &&
(strcmp(argv[1], "-c") == 0) &&
(strcmp(argv[2], SFTP_EXNAME) == 0) ) ||
( (argc == 2) &&
(strcmp(argv[1], SFTP_EXNAME) == 0) ) ) {
/* Exec the SFTP Server binary. */
execv(SFTP_BINARY, sftp_cmd);
/*
* Still here? Where's the kaboom?
* There was supposed to be an earth-shattering kaboom!
*/
error(progname, "SFTP Server binary cannot be executed.");
exit(-1);
}
/* Check whether it is a command attempt or a login. */
if (argc > 1) {
/* Command not allowed. Exit. */
error(progname, "Command not allowed.");
exit(1);
} else {
/* Print DENY_MESG and exit. */
error("", DENY_MESG);
sleep(3);
exit(2);
}
/* That's it...we should never get past the above checks. */
}
replace SFTP_BINARY and SFTP_EXNAME with your path, and run :
> gcc sftpsh.c -o sftpsh
> cp sftpsh /bin
9. now add sftpsh tot eh list of allowed shells :
> echo "/bin/sftpsh" >> /etc/shells
10. add a new user, assign a password
> useradd test
> passwd test
> vi /etc/passwd
change the user's shell to /bin/sftpsh, and homedir to //./
my test user entry looks like this :
test:x:501:502::/home/test/./hello:/bin/sftpsh
create directory in homedir of the user
> cd /home/test/
> mkdir hello
> chown test:test hello/
11. now test the results
this should not get you in :
> ssh test@localhost
but this should, chrooted
sftp test@localhost
12. if pwd shows
/hello
then you are successfull