SSH is a powerful tool. What I like most about it, is that it can also remain very simple to use, without sacrificing the security and stability it is renowned for.
What I wanted to do was setup a secure drop box. Users can upload whatever files they want, but other than that have as little access to the system as possible. Early ideas included setting up a chroot jail and/or dropping them in a custom shell. The final solution was quite a bit more simple and very graceful.
There are two magic parts to this.
Part one: forced commands through authorized_keys file. This file resides in ~/.ssh directory and contains a list of public keys that are allowed to access the system over SSH without entering a password. The connecting client would create a public/private key pair on a remote machine, then paste the public key into authorized_keys file on the machine that he or she will be accessing. A line in authorized_keys file usually looks like this:
ssh-rsa LongRandomKeyString user@remotehost
As it turns out, you can put some extra options in front of that line, and those options will affect the connections that use this key. There are quite of few of them, but the option of interest to us is command. When you change your line to read:
command="/usr/local/script" ssh-rsa LongRandomKeyString user@host
It will execute /usr/local/script when the user connects with that key. When the command returns, the connection will be automatically closed. Which brings us to…
Part two: covert scp command. Here it is:
scp -t -r /destination/path
Put this as your command into authorized_keys file, and it will put incoming transfers into /destination/path. Remove -r if you want people to only send you regular files but not directories. Option -t is what tells it to accept incoming files. If you try transferring a file over scp, this is exactly what ps aux would show: a command “scp -t filename” being executed.
A few notes about the setup.
- The accepting server will ignore all options that were given to the originating scp command. If you want to add an option to your command, it must be in the authorized_keys file.
- The accepting server will ignore the destination path given to the originating scp command. It will place files into whatever path you specify in the authorized_keys file and nowhere else.
- You must disable password logins in order for this to work. If a user does not use the keys to login, the forced command will not be executed. Simply add a line to sshd_config that reads:
And restart ssh.
- Attempts to use ssh to login to the server directly will hang at first, then close as soon as any input is detected.
- Attempts to use scp to download a file will hang until the originating command is manually killed.
So there it is, a secure write-only drop box. It’s a bit of a hassle to have the users provide their public key in advance to gain access, but when using this setup to automatically upload the files through a script, chances are you are already using passwordless logins with public keys.