Difference between revisions of "SFTP chroot"
Kynikos.bot (talk | contribs) (remove language suffix from Category:Security (English), see Talk:Table of Contents#English Category Names: Capitalization and Conflict with i18n) |
Malvineous (talk | contribs) (Add details about using bind mounts) |
||
(6 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
− | [[Category: | + | [[Category:File Transfer Protocol]] |
[[Category:Security]] | [[Category:Security]] | ||
− | |||
− | |||
OpenSSH 4.9+ includes a built-in chroot for sftp, but requires a few tweaks to the normal install. | OpenSSH 4.9+ includes a built-in chroot for sftp, but requires a few tweaks to the normal install. | ||
Line 36: | Line 34: | ||
usermod -g sftpusers | usermod -g sftpusers | ||
− | Also, set their shell to / | + | Also, set their shell to /sbin/nologin to prevent a normal ssh login: |
− | usermod -s / | + | usermod -s /sbin/nologin |
+ | |||
+ | You also need to add /sbin/nologin to /etc/shells, or the sftp-users won't be able to login. | ||
Note that since this is only for sftp, a proper chroot environment with a shell and /dev/* doesn't need to be created. | Note that since this is only for sftp, a proper chroot environment with a shell and /dev/* doesn't need to be created. | ||
Line 116: | Line 116: | ||
sshd[12399]: fatal: bad ownership or modes for chroot directory component "/path/of/chroot/directory/" | sshd[12399]: fatal: bad ownership or modes for chroot directory component "/path/of/chroot/directory/" | ||
− | + | This is a {{ic|ChrootDirectory}} ownership problem. sshd will reject SFTP connections to accounts that are set to chroot into any directory that has ownership/permissions that sshd considers insecure. sshd's strict ownership/permissions requirements dictate that every directory in the chroot path must be owned by root and only writable by the owner. So, for example, if the chroot environment is in a user's home directory both /home and /home/username must be owned by root and have permissions along the lines of 755 or 750. This does mean the user will not have write access to their home directory. See below for possible alternatives. | |
+ | |||
+ | The reason for this is to [http://lists.mindrot.org/pipermail/openssh-unix-dev/2009-May/027651.html prevent a user from escalating their privileges] and becoming root, escaping the chroot environment. | ||
If chroot environment is in user's home directory, make sure user have access to it's home directory, or user would not be able to access it's publickey, produce following error | If chroot environment is in user's home directory, make sure user have access to it's home directory, or user would not be able to access it's publickey, produce following error | ||
Permission denied (publickey). | Permission denied (publickey). | ||
+ | |||
+ | == Write access to chroot dir == | ||
+ | |||
+ | As above, if a user is able to write to the chroot directory then it is possible for them to escalate their privileges to root and escape the chroot. One way around this is to give the user two home directories - one "real" home they can write to, and one SFTP home that is locked down to keep sshd happy and your system secure. By using {{ic|mount --bind}} you can make the real home directory appear as a subdirectory inside the SFTP home directory, allowing them full access to their real home directory. | ||
+ | |||
+ | This can also be used to achieve other goals. For example, a user's home directory can be locked down per the sshd chroot rules, and bind mounts used to provide users access to other directories: | ||
+ | |||
+ | # mkdir /home/user/web | ||
+ | # mount --bind /srv/web/example.com /home/user/web | ||
+ | |||
+ | Now the user can log in with SFTP, they are chrooted to {{ic|/home/user}}, but they see a folder called "web" they can access to manipulate files on a web site (assuming they have correct permissions in {{ic|/srv/web/example.com}}. | ||
==Links & References== | ==Links & References== | ||
*[http://www.minstrel.org.uk/papers/sftp/ http://www.minstrel.org.uk/papers/sftp/builtin/] | *[http://www.minstrel.org.uk/papers/sftp/ http://www.minstrel.org.uk/papers/sftp/builtin/] | ||
*[http://www.openbsd.org/cgi-bin/man.cgi?query=sshd_config http://www.openbsd.org/cgi-bin/man.cgi?query=sshd_config] | *[http://www.openbsd.org/cgi-bin/man.cgi?query=sshd_config http://www.openbsd.org/cgi-bin/man.cgi?query=sshd_config] |
Revision as of 09:43, 23 September 2013
OpenSSH 4.9+ includes a built-in chroot for sftp, but requires a few tweaks to the normal install.
Contents
Installation
This package is available in the core repository. To install it, run
# pacman -S openssh
Configuration
In /etc/ssh/sshd_config, modify the Subsystem line for sftp:
Subsystem sftp internal-sftp
At the end of the file, add something similar to the following for a group:
Match Group sftpusers ChrootDirectory %h ForceCommand internal-sftp AllowTcpForwarding no
Or for a user:
Match User username ChrootDirectory %h ForceCommand internal-sftp
The %h represents the users home directory.
Change ownership of chrooted dir to root (for more details see at the end):
chown root ~user
Restart sshd:
# /etc/rc.d/sshd restart
Adding new chrooted users
If using the group method above, ensure all sftp users are put in the appropriate group, i.e.:
usermod -g sftpusers
Also, set their shell to /sbin/nologin to prevent a normal ssh login:
usermod -s /sbin/nologin
You also need to add /sbin/nologin to /etc/shells, or the sftp-users won't be able to login.
Note that since this is only for sftp, a proper chroot environment with a shell and /dev/* doesn't need to be created.
Their chroot will be the same as their home directory. The permissions are not the same as a normal home, though. Their home directory must be owned as root and not writable by another user or group. This includes the path leading to the directory. My recommendation is to use /usr/local/chroot as a root and build the home directories under that.
Logging
1)
The user will not be able to access /dev/log
. This can be seen by running strace
on the process once the user connects and attempts to download a file. Create the sub-dircetory dev
in the ChrootDirectory
, for example:
sudo mkdir /usr/local/chroot/theuser/dev sudo chmod 755 /usr/local/chroot/theuser/dev
syslog-ng
will create the device /usr/local/chroot/theuser/dev/log
once configured.
2)
Add to /etc/syslog-ng/syslog-ng.conf
a new source for the log and add the configuration, for example change the section:
source src { unix-dgram("/dev/log"); internal(); file("/proc/kmsg"); };
to:
source src { unix-dgram("/dev/log"); internal(); file("/proc/kmsg"); unix-dgram("/usr/local/chroot/theuser/dev/log"); };
and append:
#sftp configuration destination sftp { file("/var/log/sftp.log"); }; filter f_sftp { program("internal-sftp"); }; log { source(src); filter(f_sftp); destination(sftp); };
(Optional) If you'd like to similarly log SSH messages to it's own file:
#sshd configuration destination ssh { file("/var/log/ssh.log"); }; filter f_ssh { program("sshd"); }; log { source(src); filter(f_ssh); destination(ssh); };
(From Syslog-ng#Move_log_to_another_file)
3)
Edit /etc/ssh/sshd_config
to replace all instances of internal-sftp
with internal-sftp -f AUTH -l VERBOSE
4)
Restart logging and SSH:
/etc/rc.d/syslog-ng restart /etc/rc.d/ssh restart
/usr/local/chroot/theuser/dev/log
should now exist.
Testing your chroot
# ssh username@localhost
should refuse the connection or fail on login. The response varies, possibly due to the version of OpenSSH used.
# sftp username@localhost
should place you in the chroot'd environment.
Troubleshooting
Error while trying to connect
Write failed: Broken pipe Couldn't read packet: Connection reset by peer
If you also find similar message in /var/log/auth.log
sshd[12399]: fatal: bad ownership or modes for chroot directory component "/path/of/chroot/directory/"
This is a ChrootDirectory
ownership problem. sshd will reject SFTP connections to accounts that are set to chroot into any directory that has ownership/permissions that sshd considers insecure. sshd's strict ownership/permissions requirements dictate that every directory in the chroot path must be owned by root and only writable by the owner. So, for example, if the chroot environment is in a user's home directory both /home and /home/username must be owned by root and have permissions along the lines of 755 or 750. This does mean the user will not have write access to their home directory. See below for possible alternatives.
The reason for this is to prevent a user from escalating their privileges and becoming root, escaping the chroot environment.
If chroot environment is in user's home directory, make sure user have access to it's home directory, or user would not be able to access it's publickey, produce following error
Permission denied (publickey).
Write access to chroot dir
As above, if a user is able to write to the chroot directory then it is possible for them to escalate their privileges to root and escape the chroot. One way around this is to give the user two home directories - one "real" home they can write to, and one SFTP home that is locked down to keep sshd happy and your system secure. By using mount --bind
you can make the real home directory appear as a subdirectory inside the SFTP home directory, allowing them full access to their real home directory.
This can also be used to achieve other goals. For example, a user's home directory can be locked down per the sshd chroot rules, and bind mounts used to provide users access to other directories:
# mkdir /home/user/web # mount --bind /srv/web/example.com /home/user/web
Now the user can log in with SFTP, they are chrooted to /home/user
, but they see a folder called "web" they can access to manipulate files on a web site (assuming they have correct permissions in /srv/web/example.com
.