Second post of this OpenSSH series. Here I'll try to explain (mainly to myself ;) ) what I understood about this three options, which can give you some flexibility with your SSH and/or SFTP server. Sorry for all this theory, but I'm trying to understand how this works.
ChRoot
chroot (CHange ROOT) is a function of UNIX sistems. Wikipedia (Wikipedia Chroot) says that it change the base directory to which the processes refers to and that's a function included in the unix kernel. In other words, it temporarly changes the location of root directory.
In our SFTP server we are using chroot to limit the locations a user can access to his home directory. But beware: when we change the location of root, we change this for EVERYTHING. A simple example that happened to me.
In one of my first attemps to put up an SFTP server with chrooting, I wrote an invalid ForceCommand argument, like ForceCommand /usr/lib/openssh/. As a result, when I restarted ssh and i tried to login, I received a (for me) strange error: /bin/bash: No such file or directory . WHAT????? In which universe am I that /bin/bash has ceased to exists??? That was my reaction. Then I started searching a solution to this problem, and found it. ChRoot option, as already said, changes the root directory for the user logging in. Let's say that user rjdio was chrooted to his home directory /home/rjdio. For him, THAT is the root. So, once connected via SFTP/SSH, the client (putty, winscp or other) requested /bin/bash to start using the requested service. But, thanks to chroot, the root directory was changed at the login for user rjdio, so what the client was really requesting was /home/rjdio/bin/bash, which obviously didn't exist. And the client returned that strange error.
Depending on your goal, I know of two ways to overcome this problem.
- If you want to create a limited SSH account, you must provide in some way all the necessary programs (bash, ls, mkdir, cp, ... I said ALL the necessary programs!) . I didn't try it myself, but this seems to be a good howto for this goal: Chroot Jail SSH access.
- If you just need to limit access with SFTP, you can use ForceCommand internal-sftp.
ForceCommand
ForceCommand option forces the execution of some command (as far as I understood, ANY command) at login time, for any user it refers to.
The typical example is probably the most used internal-sftp which I'm going to explain in a few lines. Other than that, one example of what I can achieve with this option is Two factor authentication. In few words, they put a bash script in ForceCommand that connected to some API, which sent an SMS with a token, which had to be inserted within 30 seconds to be authenticated in the shell. Or simply you can send an email to warn that someone logged in your server.
Anyway, ForceCommand internal-sftp in combination with ChRoot is a powerful combination. Essentially, you are forcing the user into an SFTP server inside the sshd daemon. In some way, it's like a very limited shell, with only the SFTP command. The great plus of this kind of solution is that your user is chrooted (so he cannot access to any of the standard UNIX commands) but he can access using ONLY the SFTP commands.
Subsystem
Subsystem seems to be the least documented feature of OpenSSH. Or, at least, I had to dig very much the internet to find something, so I hope not to say something completely wrong.
Anyway, it's something like a way to recall REMOTELY one or multiple set of command. For commonly used implementation, it behaves like an alias for the remote system. An example (I still have to try it, it's just to clarify):
Subsystem backup /bin/cp /home
This subsystem copies the home directory of the user recalling this subsystem into the remote server. You can call this subsystem via command line:
ssh -s backup remote.server.com
and it will automatically execute the copy command.
The most common use of subsystems is obviously one of there two:
Subsystem sftp internal-sftp
Subsystem sftp /usr/lib/openssh/sftp-server
The first recalls the built-in sftp server of SSH, the second, if I didn't misinterpret, it's approximately the same but in an external command.
I've still got to make some tests, like removing the Subsystem sftp line and check if I can connect anyway, plus setting some other subsystem just for fun and setting a ForceCommand to do something strange, but this is what I understood for the moment.
Useful References:
Again, sorry for this mainly theorical post. I hope I didn't write too many wrong thing, in case please tell me what I misinterpreted.
Labels: bash, ubuntu