[prev in list] [next in list] [prev in thread] [next in thread] 

List:       rsync
Subject:    Re: Security model of rsync + ssh
From:       u7uif48c () umail ! furryterror ! org (Zygo Blaxell)
Date:       1999-05-25 7:01:46
[Download RAW message or body]

In article <3748C4BD.120E4AEB@bayoffice.net>,
Mike Ireton  <mike@bayoffice.net> wrote:
>	I have been using rsync now for a few months to keep backups of machine
>configurations, mail spools, and user home directories with much
>success. I currently use ssh in conjunction with rsync, which works
>nicely because I run the ssh authentication agent on my machine and the
>script takes advantage of the agent. I now want to expand my backups
>substantially and make them truely unattended. But I am running into
>some security roadblocks and I am hoping that someone on this list has
>solved some or all of these problems before.

Been there, done that, with a lot of tools before either rsync or ssh.

>	The model I am working with will be numerous remote machines, say 100
>on my wan, all backing up certain configuration data, home directories,
>and mail spool files, to a central file server. I will have to be able
>to preserve owner, group, permissions, etc when storing these on the
>server (root perms needed). The backups also need to be fire and forget
>- no operator will be around to supply passwords. I also want to avoid
>the 'trusted host' syndrome and ensure that if one of my remote sites
>are broken into (a reality that should always be considered), that the
>intruder will not be able to use that access to springboard into any of
>the other remote sites or the central file server. Encryption of the
>data stream is not required (point-to-point links) but would be nice to
>have available. 

I have real problems trusting just about anything to transfer a directory
hierarchy.  I certainly wouldn't run the rsync server (writing) side
with root privilege if I believed that its clients might be compromised,
except possibly in rsyncd mode (which uses chroot).

I would generate a file on the client side that contained a shell script
full of chown/chmod commands (properly quoted) and send that file to
the server to preserve permissions/ownership and maybe also symlinks.
This is a matter of a short Perl script.  On the server I would run rsync
as an unprivileged user, I would not preserve permissions on files
transferred, and I would hide the entire directory on the server under a
mode-700 directory so that malicious or unqualified users on the server
machine can't interfere with the data even if they have co-operation
from a compromised client.  I would maybe give each client its own user
ID on the server so that compromise of one client doesn't lead to access
(or damage) to another client's files.

The problem with giving rsync (or any other file-copying Unix utility)
high privilege levels is complex and the solution has to be designed in
from the start.  What happens if someone asks an rsync server to transfer
the following files (in this order):

	"foo" symlink to "/etc"
	"foo/passwd" regular file

Is the rsync protocol capable of expressing this (i.e. if someone cracks
your client, and they install a trojan rsync client, what can it do to
your server with the privileges it has)?  Running strace here to see
the data stream, rsync does seem to transfer symlinks first, but the
data stream seems to use a tree-based file enumerating structure which
would make it impossible to say "foo/passwd" if you had already defined
"foo" as a symlink, unless you put a slash in a filename component (does
rsync actually check for any of that?).  Without reading the source in
depth I don't know if rsync is secure against all possible data stream
attacks.  I would prefer to design a system assuming that rsync is
insecure even if it _was_ provably secure, so that I will have a second
line of defense in case of bugs.

Will rsync detect the replacement of an existing directory (i.e. one that
has been created) by a symlink?  Consider an attacker who has unprivileged
access to the server but owns a client.  The attacker gets his client
rsync (which he controls) to write some world-writable directories on
the server, then from his unprivileged user ID on the server he replaces
those directories with symlinks to /etc and other sensitive directories
while the privileged server rsync process is writing data from the
client system.  This is why I suggest chmod 700 above.

tar and cpio, for contrast, are _totally_ insecure against these kinds
of attack.  If I can get you to untar my data stream as root on your box,
I can own your box.  If I can build the data stream after I know something
about you and your system, I can usually get any other user account too.

If the rsync command-line had support for chroot(), the problems described
above would all be solved...if (and only if) the server side ran as root.
Non-root users of rsync would still have the same problems.

>	After reviewing the documentation for rsync with these needs in mind, I
>was not convinced that I could accomplish the above with rsync's host
>and password based access model. Using rsync over ssh (what I do now for
>the smaller backup set now run from my workstation), however, does
>provide some of the security I desire. 

ssh is cool.  rsync is cool.  The pair of them solves so many problems
and replaces so many ad-hoc solutions that I've lost count so far.  ;-)

>	The only model I have come up with thus far that gets close to what I
>want is:
>
>	1: A 'backup' (unprivlidged user) owned cron job wakes up and initiates
>rsync. It has 'sudo' privs for rsync so that it may be used to bypass
>file system security and sync files with the server.
>
>	2: It initiates an rsync session with the central file server as
>'backup'. 

I don't really see how anything involving 'sudo' in this situation
can be more secure than running the cron job as root from the start.
It looks like a lot of work to me with no real benefit, and if it's done
wrong it can be a huge loss.

>	3: The central file server is using the ssh combonation of username,
>host ip address, and host key, to authenticate the ssh connection as the
>local 'backup' user.
>
>	By allowing ssh authentication with username, host ip and host key, I
>am preventing any cracker from rooting one of my machines and then using
>anything gained to attack the file server from any location other than
>the originally compromised host. At best, the cracker would only be able
>to be authenticated as the 'backup' user on the central file server, an
>unprivilidged user.

If the cracker roots your client machine, the _entire_ machine is
lost from a security point of view (unless you can _prove_ otherwise,
or you have an OS where the meaning of 'rooting' is different from the
usual Unix meaning).  This means they can steal the machine's host key,
then all they need to do is have access to a nearby physical network
to attack you from any IP address they choose.  Host IP provides
inconvenience for busy attackers who have thousands of ports to scan,
not security against an attacker who wants your box.

>	I think that what I *really* need is a way to control the command that
>rsync invokves on the server (so I can tell it to use sudo to execute
>rsync on the server side), and a way to control what commands may be
>invoked by this user over SSH.

Yes.  RTFM(sshd) and use the "command" feature with RSAAuthentication.

You can set up RSA identities in the .ssh/authorized_keys file for any
user with directives to override the command line from the client.  This
means that an RSA identity file can actually be specific to one user, one
host, and one _command_.  

What I would do if I had to implement your spec is run the cron job on
the client as root (there's no point in starting the process without
privileges if it is just going to sudo for them later).  It will use a
non-passphrase-protected ssh identity (just like your host's key).
The trick is that on the server side this ssh identity is authorized to
execute only one command as a specific user on the server.  To use the
identity file you'd have to do something like this:

(in crontab for client)

	# Run the backups at e.g. 4:01 AM
	1 4 * * * ssh-agent backup-script

(in backup-script)

	# Load RSA key
	ssh-add ~/.ssh/identity.backup_rsync

	# Use the RSA key to authenticate with server
	rsync -e ssh ... local-directory user-on-server@server:remote-dir...

(Alternative implementation:  If all the files on the server that need
to be rsync-ed are readable by a non-root user or group, then run the
client as that user or group.)

On the server side, the .ssh/authorized_keys file for root (or some
other uid=0 account) looks like (broken up for clarity, but should all
be one line):

from="client.ip.address.here",command="rsync --server ...",no-pty,
	no-X11-forwarding,no-agent-forwarding,no-port-forwarding 
	1024 37 2342......[RSA key here]
	[RSA key cont'd]....34537 root@client.host.name.here config backups

The "from=" part is optional.  I don't think it's particularly worth
the trouble, since IP spoofing can be so easy while keeping track of
ever-shifting IP addresses of clients can be so hard.

(Alternative implementation:  If I were doing this, I would be using
a separate table of permissions and ownership, instead of feeding that
data through rsync, so it's not necessary for the server rsync to have
root privileges at all.  In that case, I can run 'sshd' as a non-root
user on a non-standard port, so that even compromises of ssh _itself_
are contained within an unprivileged account on the server.)

You do have to find out what rsync wants for the remote command so you
can set up the authorized_keys file.  However, this is generally constant
between invocations of rsync, so you only have to find out what it's
going to be once.  For simpler maintenance (since you have hundreds of
nearly-identical rsync command lines to maintain in this file) you might
just put it in a script and supply the host's name as a parameter, e.g.:

	from="12.34.56.78",command="rsync-wrapper 12.34.56.78",...

Note that your clients cannot use any different rsync parameters without
also changing the configuration on the server.

If your authorized_keys files are getting to be too big, you can scale
up by adding more user accounts on the server and splitting the clients
between the user accounts so that each account is a few hundred K in size.

-- 
Zygo Blaxell, Linux Engineer, Corel Corporation.  zygob@corel.ca (work) or
zblaxell@furryterror.org (play).  Opinions above are my own, not Corel's.
Linux washu 2.2.8 #2 Thu May 13 21:14 EDT 1999 i686 up 1 day, 9:45
Linux naga 2.0.36 #1 Dec 29 13:11 EST 1998 up 20 days, 9:09

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic