My question is, how do I restrict the command to just this SFTP transfer in the public key that is generated?
There are 2 methods for doing this.
1. -- Restricting through sshd
This method involves setting up the SFTP feature within your SSH daemon,
sshd. This is controlled through the
/etc/ssh/sshd_config configuration file. NOTE: This will restrict the user,
backup to only be allowed to SFTP into the server.
Subsystem sftp internal-sftp
## You want to put only certain users (i.e users who belongs to sftpusers
## group) in the chroot jail environment. Add the following lines at the end
## of /etc/ssh/sshd_config
Match User backup
2. -- Restricting through authorized_keys
This method doesn't involve any changes to the
sshd_config file. You can limit a user + a SSH key to a single command via the
command= feature which you've already mentioned in your question. The trick is in what command you include. You can put the SFTP server in this
command= line, which has the same effect as setting up the SFTP server in your
# User backup's $HOME/.ssh/authorized_keys file
command="/usr/libexec/openssh/sftp-server" ssh-dss AAAAC8ghi9ldw== backup@host
NOTE: if the user has write access to
~/.ssh/authorized_keys, they can read and/or modify it. For example, they could download it, edit it, and reupload it stripping away the
commmand=..., granting him unfettered command access, including the shell. If the user has write access to
~/.ssh, they could also simply unlink and recreate the file, or
chmod it to write access. Many possible solutions exist, such as putting the
~/.ssh/authorized_keys files away in a non-user-writable place, such as with:
Match Group sftponly
And since I am on a dynamic IP address, how do I overcome the "missing known host" problem each time my IP changes?
This is trickier but doable using the
from= feature within the
authorized_keys file as well. Here we're limiting access from only the host,
from="somehost.dyndns.org",command="/usr/libexec/openssh/sftp-server",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-dss AAAAC8ghi9ldw== backup@host
The additional settings after the
command= are equally important, since they'll limit the use of SSH key even further.
breakdown of features
from='hostname1,hostname2,'' - Restricts access from the specified IP or hostname patterns
command='command' - Runs the specified command after authentication
no-pty - Does not allocate a pty (does not allow interactive login)
no-port-forwarding - Does not allow port forwarding
no-X11-forwarding - user won't be able to remove display X11 GUIs
no-agent-forwarding - user won't be able to forward through this host to other internal hosts
To get rid of the message about the "missing known hosts" you can add this SSH option to the client when it connects like so:
$ ssh -o StrictHostKeyChecking=no ....
See the man page,
ssh_config for full details about this switch.
Restricting the user's shell
For both solutions above you'll likely want to lock down the
backup user by limiting this user's shell in the
/etc/passwd file as well. Typically you'll want to set it to
scponly, but there are other choices for this as well. See this U&L Q&A titled: "Do you need a shell for SCP?" for ways of doing this.
The use of
/sbin/nologin can also be used if you opt to use the chroot feature from
sshd_config as outlined in #1 above. However if you opt to use the method outlined in #2, then you'll likely have to use
scponly or something else for the user's shell in
BONUS - Extending #2 above
If you need to expose a set of commands for this user you can also do this. Create a script like so,
case $SSH_ORIGINAL_COMMAND in
echo "Unknown command"
You then setup the
authorized_keys file like so:
command="/bin/sh /home/user/commands.sh" ssh-dss AAAAC8ghi9ldw== user@host
backup user can then run these commands like so:
$ ssh -q user@remote_host diskspace
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/dev-root 39G 2.2G 35G 6% /
$ ssh -q remote_host dirlist