SFTP with chroot depending on public key of connecting user
I want to build a server (running Debian or FreeBSD) that receives backups from different clients via sshfs. Each client should be able to read and write its own backup data, but not the data of any of the other clients.
I had the following idea: each client connects via public key auth to [email protected]. The user backup has a special authorized_keys file, like this:
command="internal-sftp" chroot="/backup/client-1/data" ssh-rsa (key1)
command="internal-sftp" chroot="/backup/client-2/data" ssh-rsa (key2)
command="internal-sftp" chroot="/backup/client-3/data" ssh-rsa (key3)
etc...
The advantage of this would be that I would not need to use a separate user for every client, and I could easily autogenerate the authorized_keys file with a script.
There is just one problem: the chroot=...
does not work. OpenSSH's authorized_keys file does not seem to have an equivalent for ChrootDirectory (which works in /etc/ssh/sshd_config, either globally or in a Match User block).
Is there a reasonably simple way to accomplish what I want using OpenSSH? Maybe using the command=...
directive in a clever way?
Alternatively, are there other SFTP servers that can do what I want?
EDIT: To make it more clear what I want to achieve: I want several clients to be able to store files on my server. Each client should not be able to see any other client's files. And I do not want to litter my server with dozens of user accounts, so I'd like an easily manageable solution for the clients to share a user account and still have no access to eachother's files.
Solution 1:
Alternatively, are there other SFTP servers that can do what I want?
yes, you can use proftpd
Prepare user environment. With ProFTPD there is no need to give to user a valid shell.
# useradd -m -d /vhosts/backup/user1/ -s /sbin/nologin user1
# passwd --lock user1
Locking password for user user1.
passwd: Success
# mkdir /vhosts/backup/user1/.sftp/
# touch /vhosts/backup/user1/.sftp/authorized_keys
# chown -R user1:user1 /vhosts/backup/user1/
# chmod -R 700 /vhosts/backup/user1/
In order to use OpenSSH public keys in a SFTPAuthorizedUserKeys, you must convert them to the RFC4716 format. You can do this with ssh-keygen tool:
# ssh-keygen -e -f user1.public.key > /vhosts/backup/user1/.sftp/authorized_keys
Setup ProFTPD
ServerName "ProFTPD Default Installation"
ServerType standalone
DefaultServer off
LoadModule mod_tls.c
LoadModule mod_sftp.c
LoadModule mod_rewrite.c
TLSProtocol TLSv1 TLSv1.1 TLSv1.2
# Disable default ftp server
Port 0
UseReverseDNS off
IdentLookups off
# Umask 022 is a good standard umask to prevent new dirs and files
# from being group and world writable.
Umask 022
# PersistentPasswd causes problems with NIS/LDAP.
PersistentPasswd off
MaxInstances 30
# Set the user and group under which the server will run.
User nobody
Group nobody
# Normally, we want files to be overwriteable.
AllowOverwrite on
TimesGMT off
SetEnv TZ :/etc/localtime
<VirtualHost sftp.example.net>
ServerName "SFTP: Backup server."
DefaultRoot ~
Umask 002
Port 2121
RootRevoke on
SFTPEngine on
SFTPLog /var/log/proftpd/sftp.log
SFTPHostKey /etc/ssh/ssh_host_rsa_key
SFTPHostKey /etc/ssh/ssh_host_dsa_key
SFTPDHParamFile /etc/pki/proftpd/dhparam_2048.pem
SFTPAuthorizedUserKeys file:~/.sftp/authorized_keys
SFTPCompression delayed
SFTPAuthMethods publickey
</VirtualHost>
<Global>
RequireValidShell off
AllowOverwrite yes
DenyFilter \*.*/
<Limit SITE_CHMOD>
DenyAll
</Limit>
</Global>
LogFormat default "%h %l %u %t \"%r\" %s %b"
LogFormat auth "%v [%P] %h %t \"%r\" %s"
ExtendedLog /var/log/proftpd/access.log read,write
Create DH (Diffie-Hellman ) group parameters.
# openssl dhparam -out /etc/pki/proftpd/dhparam_2048.pem 2048
Configure any SFTP client. I have used FileZilla
If you run ProFPTD in debug mode
# proftpd -n -d 3
In the console you will see something like the following
2016-02-21 22:12:48,275 sftp.example.net proftpd[50511]: using PCRE 7.8 2008-09-05
2016-02-21 22:12:48,279 sftp.example.net proftpd[50511]: mod_sftp/0.9.9: using OpenSSL 1.0.1e-fips 11 Feb 2013
2016-02-21 22:12:48,462 sftp.example.net proftpd[50511] sftp.example.net: set core resource limits for daemon
2016-02-21 22:12:48,462 sftp.example.net proftpd[50511] sftp.example.net: ProFTPD 1.3.5a (maint) (built Sun Feb 21 2016 21:22:00 UTC) standalone mode STARTUP
2016-02-21 22:12:59,780 sftp.example.net proftpd[50512] sftp.example.net (192.168.1.2[192.168.1.2]): mod_cap/1.1: adding CAP_SETUID and CAP_SETGID capabilities
2016-02-21 22:12:59,780 sftp.example.net proftpd[50512] sftp.example.net (192.168.1.2[192.168.1.2]): SSH2 session opened.
2016-02-21 22:12:59,863 sftp.example.net proftpd[50512] sftp.example.net (192.168.1.2[192.168.1.2]): Preparing to chroot to directory '/vhosts/backup/user1'
2016-02-21 22:12:59,863 sftp.example.net proftpd[50512] sftp.example.net (192.168.1.2[192.168.1.2]): Environment successfully chroot()ed
2016-02-21 22:12:59,863 sftp.example.net proftpd[50512] sftp.example.net (192.168.1.2[192.168.1.2]): USER user1: Login successful
And the follwoing lines in a /var/log/sftp.log
2016-02-21 22:12:48,735 mod_sftp/0.9.9[50309]: sending acceptable userauth methods: publickey
2016-02-21 22:12:48,735 mod_sftp/0.9.9[50309]: public key MD5 fingerprint: c2:2f:a3:93:59:5d:e4:38:99:4b:fd:b1:6e:fc:54:6c
2016-02-21 22:12:48,735 mod_sftp/0.9.9[50309]: sending publickey OK
2016-02-21 22:12:59,789 mod_sftp/0.9.9[50309]: public key MD5 fingerprint: c2:2f:a3:93:59:5d:e4:38:99:4b:fd:b1:6e:fc:54:6c
2016-02-21 22:12:59,790 mod_sftp/0.9.9[50309]: sending userauth success
2016-02-21 22:12:59,790 mod_sftp/0.9.9[50309]: user 'user1' authenticated via 'publickey' method
P.S.
The configured path for a file containing authorized keys (SFTPAuthorizedUserKeys) can use the %u variable, which will be interpolated with the name of the user being authenticated. This feature supports having per-user files of authorized keys that reside in a central location, rather than requiring (or allowing) users to manage their own authorized keys. For example:
SFTPAuthorizedUserKeys file:/etc/sftp/authorized_keys/%u
I want several clients to be able to store files on my server. Each client should not be able to see any other client's files. And I do not want to litter my server with dozens of user accounts, so I'd like an easily manageable solution for the clients to share a user account and still have no access to eachother's files.
with ProFTPD it's possible too. You just need a little modify my initial configuration
<VirtualHost sftp.example.net>
...
SFTPAuthorizedUserKeys file:/etc/proftpd/sftp_authorized_keys
AuthUserFile /etc/proftpd/sftp_users.passwd
CreateHome on 0700 dirmode 0700 uid 99 gid 99
RewriteHome on
RewriteEngine on
RewriteLog /var/log/proftpd/rewrite.log
RewriteCondition %m REWRITE_HOME
RewriteRule (.*) /vhosts/backup/%u
</VirtualHost>
And create one virtual account
# ftpasswd --passwd --file /etc/proftpd/sftp_users.passwd --sha512 --gid 99 --uid 99 --shell /sbin/nologin --name user1 --home /vhosts/backup
That's all. For every additional account all you need is to add his public key to the /etc/proftpd/sftp_authorized_keys
Note: the file must contain new line in the end! It's important.
Solution 2:
the
chroot=...
does not work.
No, there is nothing like that in the manual page for sshd
, describing the format of authorized_keys
file.
If you would put chroot into command=
, you would not be able to use internal-sftp
, because it is substitution of internal function call inside sshd
.
Recommended way is set up more users, if you need separation. You might also use arguments to internal-sftp
, if you don't need strict separation (for exaxmple just different working directories), such as
command="internal-sftp -d /backup/client-1/data" ssh-rsa (key1)
There is also possible to limit amount of requests using -P
option as in manual page for sftp-server
.