Secure rsync via ssh as root
Securing Rsync as Root
From http://positon.org/rsync-command-restriction-over-ssh
Storage Server
- Create rsa key if none yet
- Check: cat ~/.ssh/id_rsa.pub
- If none, create: ssh-keygen -t rsa -b 4096 -o -a 64
- Key exchange with client
- ssh-copy-id -p 2222 www.example.com">user@www.example.com
- If you want to to a manual key exchange:
- On the machine you want to connect from:
- cat ~/.ssh/id_rsa.pub
- Copy the key
- cat ~/.ssh/id_rsa.pub
- On the machine you want to connect to:
- vi ~/.ssh/authorized_keys
- Paste the key and save
- vi ~/.ssh/authorized_keys
- On the machine you want to connect from:
- Find out rsync server command via the option -e'ssh -v' by issuing a normal rsync ssh call:
- rsync -avnz -e'ssh -v' --stats --delete --progress --hard-links --numeric-ids root@client.example.com:/root/ .
- Abort with CTRL-C after a short time
- Note the line starting with "debug1: Sending command:"
- debug1: Sending command: rsync --server --sender -vnlHogDtprze.iLsf --numeric-ids . /root/
Client - Server to be backed up:
- vi /root/.ssh/authorized_keys
- Find line for server (above)
- Prepend to that line using the rsync server command from above:
- restrict,from="123.123.123.123",command="rsync --server --sender -vnlHogDtprze.iLsf --numeric-ids . /root/"
- Example for full line:
- restrict,from="123.123.123.123",command="rsync --server --sender -vnlHogDtprze.iLsf --numeric-ids . /root/" ssh-rsa AAAAB3N...PC+v root@server.example.com
- Allow multiple IPs / networks:
-
from="1.2.3.0/24,44.55.66.77"
-
-
All options: http://man.openbsd.org/sshd.8#AUTHORIZED_KEYS_FILE_FORMAT
Storage Server
- Execute rsync
- rsync -avz --stats --progress --hard-links --delete --numeric-ids root@client.example.com:/root/ .
Details for rsync sender command
- Run rsync with "-e 'ssh -v" option. Note the "sending" command, e.g.:
- rsync --server --sender -vnlHogDtprze.iLsfxC --ignore-errors --numeric-ids --inplace . /
- v = verbose
- n = dryrun
- rsync --server --sender -vnlHogDtprze.iLsfxC --ignore-errors --numeric-ids --inplace . /
Using Multiple commands with $SSH_ORIGINAL_COMMAND
http://binblog.info/2008/10/20/openssh-going-flexible-with-forced-commands/
https://www.thomas-krenn.com/de/wiki/Ausf%C3%BChrbare_SSH-Kommandos_per_authorized_keys_einschr%C3%A4nken
Scenario: Computer "apple" wants to execute commands as root on "orange".
Desired commands on "apple"
- ssh root@orange ls -ls
- rsync -a root@orange:/srv/ /backup/orange_srv/
Setup on "orange"
- vi /root/.ssh/forced_commands_apple.sh
-
#!/bin/sh # # Secure SSH_ORIGINAL_COMMAND by stripping all characters except alphanum + space export VAR_CLEAN="`echo "${SSH_ORIGINAL_COMMAND}" | tr -cd '[:alnum:] [:space:]'`" # Debugging to find out rsync ssh commands. echo "`/bin/date`: $SSH_ORIGINAL_COMMAND" >> /tmp/ssh-command-log echo "`/bin/date`: $VAR_CLEAN" >> /tmp/ssh-command-log case "${VAR_CLEAN}" in "do this") echo "hello" ;; "do that") echo "hello" ;; *) echo "Sorry. Only limited commands are available to you." exit 1 ;; esac
-
- chmod 700 /root/.ssh/forced_commands_apple.sh
- vi /root/.ssh/authorized_keys
- Prepend to correct line for "apple"
-
restrict,from="123.123.123.123",command="/root/.ssh/forced_commands_apple.sh"
-
- Prepend to correct line for "apple"
Now we need to find out the correct "clean" command string.
Execute the desired commands on "apple":
- ssh root@orange ls -ls
- rsync -a root@orange:/srv/ /backup/orange_srv/
Now the "clean" command strings can be found in /tmp/ssh-command-log.
The "clean" string is used in the case comparison, and the original command in the clause. See example below.
- cat /tmp/ssh-command-log
-
Die Apr 4 09:24:27 CEST 2017: ls -ls Die Apr 4 09:24:27 CEST 2017: ls ls Die Apr 4 09:25:41 CEST 2017: rsync --server --sender -logDtpre.iLsfx . /srv/ Die Apr 4 09:25:41 CEST 2017: rsync server sender logDtpreiLsfx srv
- The "clean" command string is each second line without any special characters
-
- vi /root/.ssh/forced_commands_apple.sh
-
#!/bin/sh # # Secure SSH_ORIGINAL_COMMAND by stripping all characters except alphanum + space export VAR_CLEAN="`echo "${SSH_ORIGINAL_COMMAND}" | tr -cd '[:alnum:] [:space:]'`" # Debugging to find out rsync ssh commands. #echo "`/bin/date`: $SSH_ORIGINAL_COMMAND" >> /tmp/ssh-command-log #echo "`/bin/date`: $VAR_CLEAN" >> /tmp/ssh-command-log case "${VAR_CLEAN}" in "ls ls") ls -ls ;; "rsync server sender logDtpreiLsfx srv") rsync --server --sender -logDtpre.iLsfx . /srv/ ;; *) echo "Sorry. Only limited commands are available to you." exit 1 ;; esac
-
- rm /tmp/ssh-command-log
If you modify the command, or want to add a new one you have to repeat the whole process.