I wish to allow Bob to only access files in directory /var/www/main/open via sftp.

I've edited /etc/ssh/sshd_config, and changed Subsystem sftp /usr/libexec/openssh/sftp-server to Subsystem sftp internal-sftp, and also added the following:

Match Group allow_sftp
    ChrootDirectory /var/www/main/open
    ForceCommand internal-sftp
    AllowTcpForwarding no

I then added Bob:

useradd bob -d /var/www/main/open
passwd bob 
groupadd allow_sftp
usermod -G allow_sftp bob 
usermod -s /bin/false bob 

I then used FileZilla to access the server using Bob's credentials. It opened in Bob's new home directory /var/www/main/open, however, I was still able to access all directories on the server.

How do I limit Bob to only files in directory /var/www/main/open?

EDIT. Added responses to comments

[root@devserver ~]# cat /etc/centos-release
CentOS release 6.5 (Final)
[root@devserver ~]# sshd -V
sshd: illegal option -- V
OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013
usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]
            [-f config_file] [-g login_grace_time] [-h host_key_file]
            [-k key_gen_time] [-o option] [-p port] [-u len]
[root@devserver ~]# sshd -d -d -d -d -p 9999
sshd re-exec requires execution with an absolute path
[root@devserver ~]#


[root@devserver ~]# /usr/sbin/sshd -d -d -d -d -p 9999
debug2: load_server_config: filename /etc/ssh/sshd_config
debug2: load_server_config: done config len = 694
debug2: parse_server_config: config /etc/ssh/sshd_config len 694
debug3: /etc/ssh/sshd_config:21 setting Protocol 2
debug3: /etc/ssh/sshd_config:36 setting SyslogFacility AUTHPRIV
debug3: /etc/ssh/sshd_config:42 setting PermitRootLogin no
debug3: /etc/ssh/sshd_config:66 setting PasswordAuthentication yes
debug3: /etc/ssh/sshd_config:70 setting ChallengeResponseAuthentication no
debug3: /etc/ssh/sshd_config:81 setting GSSAPIAuthentication yes
debug3: /etc/ssh/sshd_config:83 setting GSSAPICleanupCredentials yes
debug3: /etc/ssh/sshd_config:97 setting UsePAM yes
debug3: /etc/ssh/sshd_config:100 setting AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
debug3: /etc/ssh/sshd_config:101 setting AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
debug3: /etc/ssh/sshd_config:102 setting AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
debug3: /etc/ssh/sshd_config:103 setting AcceptEnv XMODIFIERS
debug3: /etc/ssh/sshd_config:109 setting X11Forwarding yes
debug3: /etc/ssh/sshd_config:133 setting Subsystem sftp internal-sftp
debug3: checking syntax for 'Match Group allow_sftp'
debug1: sshd version OpenSSH_5.3p1
debug3: Not a RSA1 key file /etc/ssh/ssh_host_rsa_key.
debug1: read PEM private key done: type RSA
debug1: private host key: #0 type 1 RSA
debug3: Not a RSA1 key file /etc/ssh/ssh_host_dsa_key.
debug1: read PEM private key done: type DSA
debug1: private host key: #1 type 2 DSA
debug1: rexec_argv[0]='/usr/sbin/sshd'
debug1: rexec_argv[1]='-d'
debug1: rexec_argv[2]='-d'
debug1: rexec_argv[3]='-d'
debug1: rexec_argv[4]='-d'
debug1: rexec_argv[5]='-p'
debug1: rexec_argv[6]='9999'
debug3: oom_adjust_setup
Set /proc/self/oom_score_adj from 0 to -1000
debug2: fd 3 setting O_NONBLOCK
debug1: Bind to port 9999 on
Server listening on port 9999.
debug2: fd 4 setting O_NONBLOCK
debug1: Bind to port 9999 on ::.
Server listening on :: port 9999.
  • Stupid question... you have restarted sshd after making sshd_config changes ? I.e. service sshd restart. If that's not it, I suggest you post centos/sshd versions. Also try starting sshd with debugging turned on. – Lqueryvg May 7 '14 at 12:46
  • Yes, I restarted sshd. What do you mean by posting centos/sshd versions? Can you elaborate on "sshd with debugging"? – user1032531 May 7 '14 at 12:59
  • cat /etc/centos-release (you are running centos, right ?) sshd -V to get sshd version. Debug as follows: sshd -d -d -d -d -p 9999 then connect with client as follows (from another window on same host): sftp -oPort=9999 bob@localhost – Lqueryvg May 7 '14 at 13:15
  • If chroot is working, you should see in the output something like... debug3: safely_chroot: checking '/var/www/main/open' Changed root directory to "/var/www/main/open" – Lqueryvg May 7 '14 at 13:17
  • Thanks Lqueryvg, Please see the now content on my original post. Note that I wasn't able to sshd as described. Also, where should I see your described output. – user1032531 May 7 '14 at 13:22

I think the question you asked is essentially answered, even though it might not be working exactly as you require just yet.

For the chroot environment to work for directory /var/www/main/open every path element must be owned by root and writable only by root. E.g.

drwxr-xr-x. 6 root root 4.0K Apr  4 00:57 /var/www/

Also, these must be real directories - not symbolic links. All of this is to stop someone tampering with the chroot'ed environment by (for example) renaming one of the directories along the path and replacing it with their own.

If components of the chroot directory do not have sufficiently restrictive ownerships or permissions, then you'll see an error of the following form:

bad ownership or modes for chroot directory component "/a/b/"

Debug as follows:

Start the sshd in debug mode, running on a non-standard port. The benefit of doing it this way is that you don't have to change your sshd config or stop/start the sshd which is running on the standard port 22. Also, the debug messages come out in the same window, so you don't have to go searching for an external messages file.

/usr/sbin/sshd -d -d -d -d -p 9999

Connect to the "test" sshd as follows:

sftp -oPort=9999 bob@localhost
  • Thanks Lqueryvg. Great job answering this question. I appreciate your help, and learned plenty in the process. – user1032531 May 7 '14 at 19:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.