rsync server under CentOS 8 with SELinux enabled

Here is a quick and useful tip on how to run a rsync daemon under CentOS 8 with SELinux in Enforcing mode.
There are three basic steps:

  1. rsync daemon installation and configuration.
  2. firewall configuration.
  3. SELinux configuration.

STEP 1) rsync daemon installation and configuration.

Under CentOS 8 rsync daemon files are in a separate rpm package rsync-daemon (more on the subject rsync daemon in CentOS 8):

[root@srv ~]# dnf install -y rsync-daemon
Last metadata expiration check: 2:45:48 ago on Thu Apr  7 07:40:42 2022.
Dependencies resolved.
 Package                     Architecture          Version                        Repository             Size
 rsync-daemon                noarch                3.1.3-14.el8                   baseos                 43 k

Transaction Summary
Install  1 Package

Total download size: 43 k
Installed size: 17 k
Downloading Packages:
rsync-daemon-3.1.3-14.el8.noarch.rpm                                           98 kB/s |  43 kB     00:00    
Total                                                                          81 kB/s |  43 kB     00:00     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                      1/1 
  Installing       : rsync-daemon-3.1.3-14.el8.noarch                                                     1/1 
  Running scriptlet: rsync-daemon-3.1.3-14.el8.noarch                                                     1/1 
  Verifying        : rsync-daemon-3.1.3-14.el8.noarch                                                     1/1 



The configuration is in /etc/rsyncd.conf and it is simple enough, just append to the end of the configuration file the following lines:

hosts allow =
hosts deny  = *

       read only = yes
       path = /mnt/storage
       comment = storage

Of course, check if the hosts allow and hosts deny are present in the current configuration and just add the IP of the client to this list separated with a comma.
The shared directory is /mnt/storage, but it could be even “/”, i.e. the root of the filesystem tree.

Start the rsync daemon and check if it is running properly:

[root@srv ~]# systemctl start rsyncd
[root@srv ~]# systemctl status rsyncd
● rsyncd.service - fast remote file copy program daemon
   Loaded: loaded (/usr/lib/systemd/system/rsyncd.service; disabled; vendor preset: disabled)
   Active: active (running) since Thu 2022-04-07 08:19:50 UTC; 4s ago
 Main PID: 950697 (rsync)
    Tasks: 1 (limit: 409567)
   Memory: 800.0K
   CGroup: /system.slice/rsyncd.service
           └─950697 /usr/bin/rsync --daemon --no-detach

STEP 2) Configure the CentOS 8 firewall.

CentOS 8 uses firewallD daemon, which could be controlled by the cli command utility firewall-cmd. The following line is enough to allow an IP to connect to the running rsync daemon on 873 port (the default rsync daemon port).

[root@srv ~]# firewall-cmd --zone=public --add-rich-rule="rule family="ipv4" source address="" port protocol="tcp" port="873" accept"

The would be allowed to connect to the rsync daemon.
If it is needed for this option to be persistent an additional option “–permanent” should be added and a reload command issued:

[root@srv ~]# firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="" port protocol="tcp" port="873" accept"
[root@srv ~]# firewall-cmd --reload

STEP 3) SELinux configuration.

When the SELinux is enabled and is in Enforcing mode there are several rsync SELinux options, which should be considered. In fact, to configure SELinux to allow rsync daemon to access the file system, at least rsync_export_all_ro should be enabled:

[root@srv ~]# setsebool -P rsync_export_all_ro 1

“-P” means the option is persistent over reboots.
There are more options like exporting the rsync to be writable by the rsync daemon and so on:

[root@srv ~]# getsebool -a|grep rsync
postgresql_can_rsync --> off
rsync_anon_write --> off
rsync_client --> off
rsync_export_all_ro --> on
rsync_full_access --> off
rsync_sys_admin --> off

STEP 4) rsync client command to sync a content.

Here is an example client rsync command, which synchronizes a directory ( from a remote server to a local directory (/mnt/storage/files/).

[root@srv ~]# rsync --verbose --progress --stats --recursive --times --perms --links --owner --group --hard-links --devices --specials /mnt/storage/files/

The command enables multiple options to preserve the users, groups, permissions, times, and more.


[root@srv ~]# rsync --verbose --progress --stats --recursive --times --perms --links --owner --group --hard-links --devices --specials /mnt/storage/files/

receiving incremental file list
rsync: change_dir "/mnt/storage/files" (in storage) failed: Permission denied (13)

Number of files: 0
Number of created files: 0
Number of deleted files: 0
Number of regular files transferred: 0
Total file size: 0 bytes
Total transferred file size: 0 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 94
Total bytes sent: 8
Total bytes received: 94

sent 8 bytes  received 94 bytes  68.00 bytes/sec
total size is 0  speedup is 0.00
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1663) [Receiver=3.1.3]
rsync: read error: Connection reset by peer (104)

The error is because SELinux prevents rsync daemon to access the /mnt/storage/files directory. After enabling the rsync_export_all_ro the error disappears and the rsync starts the synchronizing the directories.

Leave a Reply

Your email address will not be published. Required fields are marked *