lsync configuration for using non-root logins

freshpowder picture freshpowder · Aug 26, 2013 · Viewed 19k times · Source

I have searched for > 5 days, tried numerous tricks and tips and even tried to get the author of lsync to help but all in vain.

I have 2 Red Hat 6.3 web servers that need to sync up their image directories when an image is uploaded. We can't control which server it gets uploaded to but it does not get loaded to the other one when it's uploaded.

I simply need to be able to tell lsync to use another user's credentials other than root. Our information security team will not allow passwordless root access. Can't say that I blame them.

I have an account that has sudo access to perform everything it needs to get the files to their destination. Although I can get rsync to perform the sync just fine, it fails with a permission denied error when run from lsync.

I can even copy the command that is executed by lsync from the log, remove the square brackets and it syncs up successfully. So, I'm pretty sure it's lsync that is causing the problem. Simply because it is being run as root. The shell script forces it to run as root. I've even tried to change it to a non-root account and all the supporting files were changed along with the script and it still refuses to sync up.

Here's the details on the scripts and files that I have: OS: Red Hat Linux version 6.3 (Santiago) lsyncd config file:

 ----
 -- User configuration file for lsyncd.
 --
 -- Simple example for default rsync, but executing moves through on the target.
 --
 -- For more examples, see /usr/share/doc/lsyncd*/examples/
 -- 
 -- sync{default.rsyncssh, source="/var/www/html", host="localhost", targetdir="/tmp/htmlcopy/"}

settings{
    logfile = "/var/log/lsyncd.log",
    statusFile = "/var/log/lsyncd-status.log",
    delay = 1,
}
sync {
    default.rsyncssh,
    source="<Absolute path to source directory>",
    host      = "<Host IP>",
    targetdir = "<Absolute path to target directory>",
    rsync = {
        binary = "/usr/bin/rsync",
        rsh = "sudo -u <Domain>\\<User ID> ssh",
        sparse = true,
        update = true,
        links = true,
        times = true,
    }
}

rsyncd.conf file:

log file = /var/log/rsyncd.log
pid file = /var/log/rsyncd.pid
allow = localhost
deny = *
list = true
uid = 16777218
gid = 16777222
read only = false
timeout=600
use chroot = true

[Test1]
path = "<Absolute path to target/source>"
comment = Test for remote transfer

The rsyncd.conf file was changed to use a different uid/gid as this is what I wanted it to be changed to.

Here is the error log from lsyncd.log:

Thu Aug 22 07:58:57 2013 Debug: daemonizing now.
Thu Aug 22 07:58:57 2013 Function: Inotify.addWatch(<Absolute Path to Source> )
Thu Aug 22 07:58:57 2013 Inotify: addwatch( <Absolute Path to Source> )-> 1 
Thu Aug 22 07:58:57 2013 Call: getAlarm( )
Thu Aug 22 07:58:57 2013 Alarm: runner.getAlarm returns: (true)
Thu Aug 22 07:58:57 2013 Masterloop: immediately handling delays.
Thu Aug 22 07:58:57 2013 Call: cycle( )
Thu Aug 22 07:58:57 2013 Function: invokeActions( "Sync1", (Timestamp: 5491559.47) )
Thu Aug 22 07:58:57 2013 Normal: recursive startup rsync: <Absolute Path to Target> -> <Host IP>:<Absolute Path to Target>
Thu Aug 22 07:58:57 2013 Exec: /usr/bin/rsync [--delete] [--ignore-errors] [-usltS] [--rsh=sudo -u <Domain>\<User ID> ssh] [-r] [<Absolute Path to Source>] [<Host IP>:<Absolute Path to Target>]
Thu Aug 22 07:58:57 2013 Function: write( (Timestamp: 5491559.47) )
Thu Aug 22 07:58:57 2013 Statusfile: writing now
Thu Aug 22 07:58:57 2013 Call: getAlarm( )
Thu Aug 22 07:58:57 2013 Alarm: runner.getAlarm returns: (false)
Thu Aug 22 07:58:57 2013 Masterloop: going into select ( no timeout )
rsync: Failed to exec sudo: Permission denied (13)
rsync error: error in IPC code (code 14) at pipe.c(84) [sender=3.0.6]
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in IPC code (code 14) at io.c(600) [sender=3.0.6]
Thu Aug 22 07:58:57 2013 Call: collectProcess( )
Thu Aug 22 07:58:57 2013 Delay: collected an event
Thu Aug 22 07:58:57 2013 Error: Temporary or permanent failure on startup of "<Absolute Path to Target>". Terminating since "insist" is not set.

NOTE: I sanitized the files and assumed I understood all of the intent of the application as to where the source and targets should be.

So, just so we're clear on the objective:

  1. I have 2 web servers that are load balanced.
  2. Images will be uploaded without control as to which server they go to.
  3. I'm designing a sync architecture using lsyncd/rsync as a daemon to update both servers when the upload occurs. This means that both servers will need to run lsyncd/rsyncd with no delete. No delete assumes that if both servers got a different image at the same time then which ever server checked the target first, it would delete the file on the target since it wasn't on the source.

They were talking about trying to figure out how to direct the images to one server and then we could use the delete option to make both servers sync accurately without worrying about having the sync services on both servers and maybe missing one because of timing. Also, don't know what will happen if one file is open and the other server tries to delete it.

I am desperate since I can't even get the author to help. Maybe it can't be done but it would seem that an app this powerful would have this one silly little flaw that would make it completely unusable by those that have security concerns.

Thanks!

Answer

edlerd picture edlerd · Oct 9, 2014

you have to set the username and the keyfile in the rsyncopts part of lsyncd.conf file (on ubuntu it is /etc/lsyncd/lsyncd.conf.lua). The keyfile must be present on the host where the lsyncd daemon is running.

sync{
  default.rsyncssh,
  source="/path/to/source",
  host="target.example.org",
  targetdir="/path/on/target",
  rsyncOpts={"-e", "/usr/bin/ssh -l someuser123 -i /home/someuser123/.ssh/id_rsa"}
}