How to Restrict an SSH Key to Allow Only Rsync/SCP File Transfers Securely


15 views

When automating file transfers between servers as root, we face a security paradox: we need privileged access while minimizing attack surface. The traditional approach of using SSH keys with IP restrictions (from="x.x.x.x") in authorized_keys provides basic security, but we can implement finer-grained controls.

OpenSSH's authorized_keys file supports the command= option to force specific commands. Here's how to implement it for rsync:

from="192.168.1.100",command="/usr/local/bin/validate-rsync.sh" ssh-rsa AAAAB3NzaC1yc2E... root@server-a

Create /usr/local/bin/validate-rsync.sh with strict permissions (700):

#!/bin/bash
# Limit to rsync operations only
case "$SSH_ORIGINAL_COMMAND" in
    rsync\ --server*)
        /usr/bin/rsync --server ${SSH_ORIGINAL_COMMAND#*rsync --server }
        ;;
    *)
        echo "Rejected: $SSH_ORIGINAL_COMMAND"
        exit 1
        ;;
esac

For additional security, constrain operations to specific directories:

#!/bin/bash
ALLOWED_DIR="/backups"

if [[ "$SSH_ORIGINAL_COMMAND" =~ ^rsync\ --server.*$ALLOWED_DIR ]]; then
    /usr/bin/rsync --server ${SSH_ORIGINAL_COMMAND#*rsync --server }
else
    echo "Access restricted to $ALLOWED_DIR only"
    exit 1
fi

The rsync package includes rrsync for this exact purpose:

from="192.168.1.100",command="/usr/bin/rrsync -ro /backups/" ssh-rsa AAAAB3NzaC1yc2E...

Options:

  • -ro: Read-only access
  • -wo: Write-only access
  • Omit both for read-write

Verify the setup works:

ssh -i /root/.ssh/rsync_key root@server-b rsync --server --sender -vlogDtpr . /backups

Attempt invalid operations to test restrictions:

ssh -i /root/.ssh/rsync_key root@server-b /bin/bash  # Should fail
  • Use separate keys for different purposes (don't reuse root's main key)
  • Rotate keys periodically
  • Monitor /var/log/auth.log for unauthorized attempts
  • Consider combining with no-port-forwarding,no-X11-forwarding,no-agent-forwarding

When automating file transfers between servers as root, we need to balance functionality with security. Traditional SSH key authentication provides full shell access by default, which creates unnecessary risk for file transfer operations.

The authorized_keys file supports several powerful restriction options. Here's how to implement them:

from="192.168.1.100",command="/usr/local/bin/rrsync /backup/",no-port-forwarding,no-X11-forwarding,no-pty ssh-rsa AAAAB3Nz... root@server-a

This configuration combines:

  • IP restriction (from=)
  • Forced command execution (command=)
  • Disabling of extraneous features

The rsync package includes rrsync (restricted rsync) which provides directory-level security. Installation steps:

# On Debian/Ubuntu
apt install rsync
cp /usr/share/doc/rsync/scripts/rrsync.gz /usr/local/bin/
gunzip /usr/local/bin/rrsync.gz
chmod +x /usr/local/bin/rrsync

Example configuration allowing only /backup directory access:

command="/usr/local/bin/rrsync -ro /backup/",no-pty,no-agent-forwarding,no-port-forwarding ssh-rsa AAAAB3Nz...

For more complex scenarios, create a wrapper script:

#!/bin/bash
# /usr/local/bin/restricted-transfer

case $SSH_ORIGINAL_COMMAND in
    "rsync --server --sender"*)
        # Allow only specific rsync operations
        exec $SSH_ORIGINAL_COMMAND
        ;;
    *)
        echo "Access denied"
        exit 1
        ;;
esac

Test with:

ssh -i transfer_key root@server-b "echo $SSH_ORIGINAL_COMMAND"
rsync -azP -e "ssh -i transfer_key" /local/path/ root@server-b:/backup/

Remember to:

  • Set proper permissions on authorized_keys (600)
  • Test from allowed and blocked IPs
  • Monitor auth.log for unauthorized attempts

For maximum security, combine with chroot:

Match User restricted-transfer
    ChrootDirectory /restricted
    ForceCommand internal-sftp
    PermitTunnel no
    AllowAgentForwarding no
    AllowTcpForwarding no
    X11Forwarding no