deajan / osync

A robust two way (bidirectional) file sync script based on rsync with fault tolerance, POSIX ACL support, time control and near realtime sync
http://www.netpower.fr/osync
BSD 3-Clause "New" or "Revised" License
927 stars 100 forks source link

enable restricted ssh connections to remote hosts #185

Open val-kulkov opened 4 years ago

val-kulkov commented 4 years ago

Unrestricted ssh connections to remote hosts using unprotected secret keys open a security hole in the remote server. To access remote resource over ssh, osync.sh must use a secret ssh key and the remote server must have the respective public key stored in authorized_keys file. An attacker who obtains access to the secret key will be able to establish ssh connections and execute arbitrary commands on the remote server.

The secret key may be protected by a passphrase, but the use of a passphrase does not work well with scripts. The security hole still remains because the script either has such passphrase or it has to obtain the passphrase from a file or another script. An attacker who gets access to such file or script will be able to recover the passphrase and use it with the secret key to obtain ssh access to the remote server.

The problem is much worse if osync.sh has to use rsync as root and run commands on the remote server as root. This is the case, for example, when osync.sh is used to synchronize Samba sysvol hierarchies on Samba DCs because it has to synchronize ownership, permissions and ACLs. An attacker who obtains access to a passwordless secret key that osync.sh uses to run commands on the remote server as root will have root access to the remote server over ssh.

To mitigate this security issue, osync.sh uses the "ssh filter" mechanism to only allow ssh connections that provide a correct $_REMOTE_TOKEN. Unfortunately, this does not solve the problem. An attacker who gets access to the configuration file will know $_REMOTE_TOKEN and will therefore be able to establish an ssh connection and execute arbitrary commands on the remote server.

This security issue can be reliably solved by employing the "restricted ssh" mechanism. To restrict a public/secret key pair to executing a single command on the remote host, authorized_keys file must contain the command="command" directive for that public key. In this case, the command supplied by the user (if any) is ignored. The specified command can take input from the ssh client however and use it in a way that does not compromise security of the remote host.

The "restricted ssh" mechanism is used by rrsync, a restricted ssh companion to rsync, and Borg backup. rrsync is included in the "rsync" package in Debian and is available at /usr/share/doc/rsync/scripts/rrsync.gz on hosts running Debian-based distros.

This is a new feature request to implement the restricted ssh mechanism in osync.sh to reliably eliminate the security hole introduced by the use of passwordless secret ssh keys. There are at least two possible approaches:

  1. Use rrsync exclusively for all synchronization between client and remote host, and
  2. Implement functionality in osync.sh that is similar to rrsync.

The second approach, a complementary script would be deployed on the remote host. Let's call that script orsync.sh. The authorized_keys file on the remote host would then contain a line like this:

command="/usr/local/bin/orsync.sh /var/lib/samba/sysvol/",no-port-forwarding,no-agent-forwarding,no-X11-forwarding ssh-ed25519 AAAAC3Nza...

This directive in authorized_keys will ensure that regardless of the command attempted by the client using a passwordless secret ssh key matching the public "AAAAC3Nza..." ssh key, the remote host will execute only /usr/local/bin/orsync.sh and with only one argument: /var/lib/samba/sysvol/. Any input from the client will be provided to the remote host in the form of environment variables, including $SSH_ORIGINAL_COMMAND.

What is essential here is that orsync must un-taint (using Perl terminology) any parameters provided by the client in order to prevent tricking orsync.sh by the client into running arbitrary commands or accessing files outside of the hierarchy specified in authorized_keys - /var/lib/samba/sysvol/ in the example above.

Thank you @deajan for your consideration.

deajan commented 4 years ago

This actually needs most of osync code directly into ssh_filter. This can be done by using the merge.sh process.

From there, only environment variables are passed from osync to ssh_filter, and then filtered for paths outside of the jail.

I'll consider this, but help would be nice.