rsync, Part II
Last month we covered setting up an rsync server for anonymous access. Listing 1 shows the sample rsyncd.conf file from last month, illustrating some options particularly useful for tightening security. Returning to our example, here's a word about setting up rsync modules (directories) at the filesystem level. The guidelines for doing this are the same as those for anonymous FTP chroot environments. The only exception is that no system binaries or configuration files need to be copied inside them for chroot purposes, as is the case with some FTP servers.
Listing 1. Sample rsyncd.conf File
The rsync configuration file needs only a little customization of paths and allowed hosts to start serving files to anonymous users. But that's a pretty narrow offering. How about accepting anonymous uploads and adding a module for authenticated users? Listing 2 outlines how to do both.
Listing 2. Additional rsyncd.conf Modules
First, we have a module called incoming, whose path is /home/incoming. The guidelines for publicly writable directories (see “Tips for Securing Anonymous FTP” in Building Secure Servers with Linux) apply, but with one important difference: for anonymous rsync, this directory must be world-executable as well as world-writable, that is, mode 0733. If it isn't set this way, file uploads fail without any error being returned to the client or logged on the server.
Some tips that apply for configuring FTP are to watch this directory closely for abuse and never make it or its contents world-readable. Also, move uploaded files out of it and into a nonworld-accessible part of the filesystem as soon as possible, perhaps with a cron job.
The only new option in the [incoming] block is transfer logging. This causes rsync to log more verbosely when actual file transfers are attempted. By default, this option has a value of no. In addition, the familiar option read-only has been set to no, overriding its global setting of yes. No similar option exists for telling rsync this directory is writable; this is determined by the directory's actual permissions.
The second part of the example defines a restricted-access module named Audiofreakz. There are three new options to discuss here. The first option, list, determines whether this module should be listed when remote users request a list of the server's available modules. Its default value is yes.
The other two new options, auth users and secrets file, define how prospective clients should be authenticated. rsync's authentication mechanism, available only when run in dæmon mode, is based on a reasonably strong 128-bit MD5 challenge-response scheme. This is superior to standard FTP authentication for two reasons. First, passwords are not transmitted over the network and therefore are not subject to eavesdropping attacks. Brute-force hash-generation attacks against the server are theoretically feasible, however.
Second, rsync doesn't use the system's user credentials; it has its own file of user name-password combinations. This file is used only by rsync and is not linked or related in any way to /etc/passwd or /etc/shadow. Thus, even if an rsync login session is somehow compromised, no user's system account is directly threatened or compromised unless you've made some poor choices regarding which directories to make available using rsync or when setting those directories' permissions.
Like FTP, however, data transfers themselves are unencrypted. At best, rsync authentication validates the identities of users, but it does not ensure data integrity or privacy against eavesdroppers. To achieve those goals you must run it over either SSH or Stunnel.
The secrets file option specifies the path and name of the file containing rsync user name-password combinations. By convention, /etc/rsyncd.secrets commonly is used, but the file may have practically any name or location—it needn't end, for example, with the suffix .secrets. This option also has no default value; if you wish to use auth users, you also must define secrets file. This example shows the contents of a sample secrets file:
watt:shyneePAT3 bell:d1ngplunkB00M!
The auth users option in Listing 2 defines which users, among those listed in the secrets file, may have access to the module. All clients who attempt to connect to this module, assuming they pass any applicable hosts allow and hosts deny ACLs, are prompted for a user name and password. Remember to set the permissions of the applicable files and directories carefully, because these ultimately determine what authorized users may do once they've connected. If auth users is not set, users are not required to authenticate, and the module is available over anonymous rsync. This is rsync's default behavior in dæmon mode.
And that is most of what you need to know to set up both anonymous and authenticated rsync services. See the rsync(8) and rsyncd.conf(5) man pages for full lists of command-line and configuration-file options, including a couple I haven't covered here that can be used to customize log messages.
Lest I forget, I haven't explained how to connect to an rsync server as a client. This is a simple matter of syntax; when specifying the remote host, use a double colon rather than a single colon and use a path relative to the desired module, not an absolute path.
For instance, to revisit the scenario in last month's example, in which the client system is called near and the remote system is called far, suppose you wish to retrieve the file newstuff.tgz and far is running rsync in dæmon mode. Suppose further that you can't remember the name of the module on far in which new files are stored. First, you can query far for a list of its available modules, as shown below:
[root@near darthelm ]# rsync far:: public Nobody home but us tarballs incoming You can put, but you can't take
(Not coincidentally, these are the same modules we set up in this month's examples; as I predicted in the previous section, the module Audiofreakz is omitted.) The directory you need is named public. Assuming you're right, the command to copy newstuff.tgz to your current working directory would look like this:
[yodeldiva@near ~]# rsync far::public/newstuff.tgz .Both the double colon and the path format differ from SSH mode. Whereas SSH expects an absolute path after the colon, the rsync dæmon expects a module name, which acts as the “root” of the file's path. To illustrate, let's look at the same command using SSH mode:
[yodeldiva@near ~]# rsync -e ssh \ far:/home/public_rsync/newstuff.tgz .These two aren't exactly equivalent, of course; whereas the rsync dæmon process on far is configured to serve files in this directory to anonymous users (i.e., without authentication), SSH always requires authentication (although this can be automated using null-passphrase RSA or DSA keys, described in Chapter 4 of Building Secure Servers with Linux). But it does show the difference between how paths are handled.
The last rsync usage I'll mention is the combination of rsync, running in dæmon mode, with Stunnel. Stunnel is a general-purpose TLS or SSL wrapper that can be used to encapsulate any simple TCP transaction in an encrypted and optionally X.509-certificate-authenticated session. Although rsync gains encryption when you run it in SSH mode, it loses its dæmon features, most notably anonymous rsync. Using Stunnel gives you encryption as good as SSH's, while still supporting anonymous transactions.
Stunnel is covered in-depth in Chapter 5 of Building Secure Servers with Linux, using rsync in most examples. Suffice it to say that this method involves the following steps on the server side:
Configure rsyncd.conf as you normally would.
Invoke rsync with the --port option, specifying some port other than 873 (e.g., rsync --daemon --port=8730).
Set up a Stunnel listener on TCP port 873 to forward all incoming connections on TCP 873 to the local TCP port specified in the previous step.
If you don't want anybody to connect “in the clear”, configure hosts.allow to block nonlocal connections to the port specified in Step 2. In addition, or instead, you can configure iptables to do the same thing.
On the client side, the procedure is as follows:
As root, set up a Stunnel listener on TCP port 873 (assuming you don't have an rsync server on the local system already using it), which forwards all incoming connections on TCP 873 to TCP port 873 on the remote server.
When you wish to connect to the remote server, specify localhost as the remote server's name. The local Stunnel process now opens a connection to the server and forwards your rsync packets to the remote Stunnel process. The remote Stunnel process decrypts your rsync packets and delivers them to the remote rsync dæmon. Reply packets, naturally, are sent back through the same encrypted connection.
Mick Bauer (mick@visi.com) is a network security consultant for Upstream Solutions, Inc., based in Minneapolis, Minnesota. He is the author of the O'Reilly book Building Secure Servers with Linux, composer of the “Network Engineering Polka” and a proud parent (of children).