2

I had a look at the restricted rsync script, rrsync, which is mentioned in man rsync. Basically the client rsync command seems to pass all of its options through, to the remote rsync command that it runs over SSH. rrsync is a 200+ line perl script that people use, to restrict which paths and options the server allows. My initial reaction to this is "arrgh". It does not help that the rsync documentation is deliberately vague about how the --server option is actually used.

I also found a 2016 bug report showing a massive security hole in rrsync. It is still not fixed.

:-(

I would prefer to define legal targets and options using rsyncd.conf. At the same time, I want to use SSH encryption and authentication to protect my connection to the rsync server.

It looks like I can do this using an ~/.authorized_keys with a dedicated SSH key, and options to restrict it like command="/usr/bin/rsync --server --daemon --config=./rsyncd.conf .",restrict. Then I can run my rsync client command using the daemon syntax: rsync -e "ssh" "$SOURCE_PATH" "$SSH_HOST"::"$RSYNC_MODULE"/"$DEST_PATH".

(If you don't use SSH keys, you could do the same thing using a dedicated user, /etc/sshd_config, Match, and ForceCommand. There is currently no equivalent of the blanket restrict though, you have to disable all the permissions individually).

Does this work reliably?

I tested a few different options. My rsync command seems to consistently launch rsync --server --daemon ., even if I add options to the client command like -vlogDtprze.iLsf --numeric-ids.

Question: Can I rely on the above? Or contrawise, is there some case where the client might need to launch the daemon server using a different set of options?

Is the third argument - . - ever set to anything else? What does it do??

1 Answer 1

1

Yes, I think this is a fairly safe assumption.

It is the natural way for it to work. Although they avoided documenting these details, it is likely it will continue to work the same in future versions. The command-line options for rsync --server are effectively part of the network protocol, and this is generally backwards-compatible.

  1. Source code
  2. "Literature review" (several recommendations, no negative feedback)

1. Source code

The source code seems fairly clear that in "daemon_over_rsh" mode, it always runs the server side with the command-line options --server --daemon . , and nothing else.

(I expect there is an option to run a different rsync, e.g. /home/alan/rsync-custom-build/rsync. But you would already know if you were doing that).

options.c

2390 void server_options(char **args, int *argc_p)
2391 {
2392         static char argstr[64];
2393         int ac = *argc_p;
2394         uchar where;
2395         char *arg;
2396         int i, x;
2397 
2398         /* This should always remain first on the server's command-line. */
2399         args[ac++] = "--server";
2400 
2401         if (daemon_over_rsh > 0) {
2402                 args[ac++] = "--daemon";
2403                 *argc_p = ac;
2404                 /* if we're passing --daemon, we're done */
2405                 return;
2406         }

main.c

 512                 server_options(args,&argc);
 513 
 514                 if (argc >= MAX_ARGS - 2)
 515                         goto arg_overflow;
 516         }
 517 
 518         args[argc++] = ".";
 519 
 520         if (!daemon_over_rsh) {
 ...
 534         }
 535 
 536         args[argc] = NULL;

Is the third argument - . - ever set to anything else? What does it do??

No. It does not do anything.

At least one non-option argument is required. Without it, rsync will print the --help message and return exit code 1. Although when I run rsync --server --daemon, the help message is written to the system log instead of to standard error (i.e. the terminal).

Although it is required, the non-option argument to rsync --server --daemon is completely ignored.

1661         if (argc < 1) {
1662                 usage(FERROR);
1663                 exit_cleanup(RERR_SYNTAX);
1664         }
1665 
1666         if (am_server) {
1667                 set_nonblocking(STDIN_FILENO);
1668                 set_nonblocking(STDOUT_FILENO);
1669                 if (am_daemon)
1670                         return start_daemon(STDIN_FILENO, STDOUT_FILENO);
1671                 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
1672         }

2. "Literature review"

Google search terms:

  • rsync daemon server (sshd_config forcecommand) OR (authorized_keys command)
  • rsync daemon mode over ssh

I scanned the first page of results. I found several positive recommendations, and no negative feedback about this specific concern. The lack of negative feedback is not strong evidence. The security hole in rrsync seems a much more significant issue to me, but I only found it because I searched for ' "rrsync" munge links '. And Google isn't finding any external references to it, only the bug report itself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.