Setting Up an Rsync Server on Linux

To set up an rsync server on Linux, you can either use the version of rsync that is supplied with your system and installed via the system's software installation interface. We prefer to get the latest version of the source from:

     http://samba.anu.edu.au/rsync/

Download then unpack the tar file:

     tar xzvf rsync-3.0.7.tar.gz

Change to the source directory, run configure and make the source:

     cd rsync-3.0.7
     ./configure
     make

Install rsync as root:

     su
     make install

Many installation guides suggest that the rsync server be run, on demand, by xinetd. This is OK for the occasionaly rsync file transfer but we think that running rsync as a daemon is a better idea. To do this, you'll need a start/stop script for init.d. Here is our script:

/etc/init.d/rsync:

     #!/bin/sh
     #
     # rsync - Script to start/stop the rsync daemon.
     #
     # Revision History:
     # ewilde      2011Mar26  Initial coding.
     #
     # chkconfig: 2345 18 92
     # description: Rsync remote file/directory synchronization daemon
     #
     # pidfile: /var/lock/subsys/rsyncd.pid
     #
     #
     # Define the install path for the rsync binary, etc.
     #
     INSTALL_PATH="/usr/local/bin"
     CONFIG_FILE="/etc/rsync/rsyncd.conf"
     PID_RSYNCDAEMON="/var/run/rsyncd.pid"
     #
     # Load the RedHat functions.
     #
     if [ -f /etc/redhat-release ]; then
         . /etc/rc.d/init.d/functions
     fi
     #
     # Check that rsync has been installed (sometimes not the case).
     #
     [ -f $INSTALL_PATH/rsync ] || exit 0
     #
     # Upon startup, we start rsync as a daemon.
     #
     start()
         {
         action "Starting rsync daemon: " \
             $INSTALL_PATH/rsync --daemon --config=$CONFIG_FILE
         return $?
         }
     #
     # Upon shutdown, we stop the rsync daemon.
     #
     stop()
         {
         echo -n "Stopping rsync daemon: "
         killproc -p $PID_RSYNCDAEMON  rsync >/dev/null 2>&1
         StopVal=$?
      if [ $StopVal = 0 ] ; then
          echo_success
      else
          echo_failure
      fi
      echo
      return $StopVal
      }

#
# See how we were called.
#
case "$1" in

      #
      # Start.
      #
      start)
          start
          RETVAL=$?
          ;;
      #
      # Stop.
      #
      stop)
          stop
          RETVAL=$?
          ;;
      #
      # Restart or reload (whatever).
      #
      restart|reload)
          stop
          start
          RETVAL=$?
          ;;
      #
      # Conditional restart.
      #
      condrestart)
          if [ -f $PID_RSYNCDAEMON ]; then
              stop
              start
              RETVAL=$?
          fi
          ;;
      #
      # Give the status of the rsync daemon.
      #
      status)
          if [ ! -f $PID_RSYNCDAEMON ]; then
              echo The rsync daemon is down
              exit 1
          fi
          echo The rsync daemon is running
          RETVAL=0
          ;;
      #
      # Help text.
      #
      *)
          echo $"Usage: $0 {start|stop|restart|condrestart|status}"
          exit 1

esac

     exit $RETVAL

After you install this script into /etc/init.d, you need to set its ownership and permissions:

     su
     chown root:root /etc/init.d/rsync
     chmod u=rwx,go=rx /etc/init.d/rsync

You will also need to add this script to the startup sequence, for example like this:

     su
     /sbin/chkconfig --add rsync
     /sbin/chkconfig rsync on

You can check that it did get added to the startup sequence like this:

     /sbin/chkconfig --list rsync

The next thing to do is create a configuration file that tells the rsync daemon how to run and which directories it should expose as modules (share points). We choose to create an rsync directory under /etc, to hold the config files:

     su
     mkdir /etc/rsync
     chown root:root /etc/rsync
     chmod u=rwx,go=rx /etc/rsync

This sample config file should give you an idea of what your config file can look like. You can add as many modules (share points) as you wish. The rsync docs describe how to assign permissions to them, etc. We have chosen not to set any permissions (not always a wise idea), but you may want to have your remote backup login before it can copy secure directories.

/etc/rsync/rsyncd.conf:

     #
     # Rsync daemon configuration file.
     #
     #
     # Global options.  These apply to all connections unless specificaly
     # overridden.
     #
     # Note that the pid file path should match the path set in the rsync daemon
     # startup script (/etc/init.d/rsync).
     #
     pid file = /var/run/rsyncd.pid
     lock file = /var/run/rsync.lock
     read only = yes
     list = yes
     uid = nobody
     gid = nobody
     #
     # Modules (share points).
     #
     [mail]
         path = /var/spool/mail
         uid = root
         gid = mail
     [mysql]
         path = /var/mysql
         uid = mysql
         gid = mysql
     [home-jsmith]
         path = /home/jsmith
         uid = jsmith
         gid = jsmith
     [home-jblow]
         path = /home/jblow
         uid = jblow
         gid = jblow

Note that, if you want to specifically exclude subdirectories from under a module, you can use the "exclude" directive, like this:

     [www]
         path = /var/www
         uid = apache
         gid = apache
         exclude = Bugzilla/ manual/

Also note that the action of the gid parameter may violate the principal of least astonishment in that it doesn't mean what you think it does. If you specify a groupname via the gid parameter, it is only that exact group which is used to obtain permission to access the files found under the module's path. To access files under several groups, you must specify them all in a list following the gid parameter.

If, instead, you wish to have rsync access the files in the module with all of the groups that the user, specified by the gid parameter, is a member of, you should specify the group as '*'. This would look like:

     [packages]
         path = /packages
         uid = jblow
         gid = *

You'll probably want to set the ownership and permissions for your new config file, like this:

     su
     chown root:root /etc/rsync/rsyncd.conf
     chmod u=rw,go=r /etc/rsync/rsyncd.conf

Now that you've completed your config file, you can start the rsync service (it should start automatically, the next time the system boots):

     su
     /etc/init.d/rsync start

From the local system, you can check that the rsync service is running by entering:

     /etc/init.d/rsync status

You can check that the rsync service is running properly, from the NAS4Free system, with this command:

     /usr/local/bin/rsync rsync://mysys

Where "mysys" is the name of the system that is running the rsync server. You should see a list of modules (share points).

If you should happen to get an error that says this:

     rsync: read error: Connection reset by peer (54)
     rsync error: error in rsync protocol data stream (12) ...

It is most likely due to a preexisting inetd or xinetd grabbing the packets being sent to port 873 (rsync). You can look in /var/log/messages on the remote system to see what's going on. If inetd or xinetd is involved, you need to get rid of the rsync configuration in /etc/inetd.conf, /etc/xinetd.conf or /etc/xinetd.d/* (probably rsync). If the rsync package was installed by an RPM, you should remove it with yum, the package manager, apt or whatever.

Also, you'll need to restart inetd or xinetd to get it to give up on the rsync port. But, be advised that xinetd in particular is quite persistent and you may have to cancel it by hand. Try (if you're running inetd, substitute its name instead):

     su
     /etc/init.d/xinetd restart

If this fails, try:

     ps x | grep xinetd
then
     kill -9 pidnum (where pidnum was returned by ps)
     /etc/init.d/xinetd restart

If you get an error that says:

     rsync: failed to connect to mysys: Connection refused (61)
     rsync error: error in socket IO (code 10) ...

It is due to a the rsync daemon not listening on port 873 (rsync). Try restarting (or starting) the daemon, especially if you've just fixed the inetd/xinetd problem described above:

     su
     /etc/init.d/rsync restart

Finally, we should say a few things about security. You'll note that we specified "uid = nobody" and "gid = nobody" in the global options and then overrode these options for each of the modules (share points). For example, the "mail" module uses "uid = root" and "gid = mail". These settings are necessary to allow rsync to have proper access to the subdirectories and files under the specified directories.

However, since we didn't specify any of the "auth users", "secrets file", "hosts allow" or "hosts deny" parameters, this essentially leaves these modules (share points) wide open to any rsync client on your system. You might want to consider at the very least a "hosts allow" parameter in the global options section of /etc/rsync/rsyncd.conf, to allow only the NAS4Free server access to the modules:

.

       .

uid = nobody
gid = nobody
hosts allow = 192.168.1.nnn

       .
       .
       .

Use the actual IP address of the NAS4Free server instead of 192.168.1.nnn.