Linux 下 Rsync 文件同步与增量备份

By | 最新修改:2026-01-28

前言

什么是 Rsync

Rsync ,即“Remote Synchronous”,“远程同步”的意思,是一款开源自由的 Linux 文件传输软件,通常用作为增量备份的工具。它可以本地与本地不同目录间互相同步,也可以本地与远程服务器端进行同步,更可以远程对远程进行增量备份。

这里的同步不是实时同步,要想实时,那么要用到其他工具与之协同。

Rsync 还可以配合 inotify、sersync 和 Crontab 进行实时、定时或时间间隔式的同步。

同步文件的原因

由于作者要在本地 Ubuntu 系统开发 WordPress 插件,然后将代码同步到服务器端的 LEMP 架构供运行和测试。

为什么是 Rsync

用 SCP 来传输不太方便,不仅没有提供增量备份,并且 Rsync 可以设置指定传输过来的文件属主和属组,毕竟 PHP-FPM/Nginx 需要设置为特定用户读写其站点目录,这些都是 SCP 没有的。

本文的主要内容和写作目的

本文介绍如何配置 Rsync、(远程)目录权限,以及本地与服务器同步的参数配置。

作者写下这篇文章的目的在于让读者避免踩坑。这个软件就这么简单,就是这么配置和使用的,并没有多复杂和可怕,本文是作者踩坑踩出来的感悟,并且分享出来。


客户端和服务端

接下来的每个操作系统第一行命令安装 Rsync 的客户端,第二行安装服务端。

如果仅有一行命令,则表示客户端和服务端都是通过这行命令安装。

本章节将介绍在 CentOS 7、CentOS Stream、RHEL / RockyLinux、Ubuntu 和 Arch Linux 上安装 Rsync 的客户端和服务端。

CentOS 7 安装

sudo yum install -y rsync

RHEL,AlmaLinux,Rocky Linux 8,9,10 或 CentOS Stream安装

sudo dnf install -y rsync
# 服务器端守护进程
sudo dnf install -y rsync-daemon

Ubuntu 安装

sudo apt-get install -y rsync
# 安装完成需要创建文件 /etc/rsyncd.conf
sudo touch /etc/rsyncd.conf
# 再启动守护进程

Arch Linux 安装

sudo pacman -S rsync

服务器端

Rsync 不仅可以采用 SSH 加密传输,而且可以运行守护进程,无加密的方式。

因为要让传输过来的文件具有指定的属主和属组,因此本文选用 Rsync 协议,也就是守护进程方式。

目录设置

因为是 Web 项目,所以要有站点根目录。根据计划,通过 Rsync 由电脑本地上传到服务器。

这里新建一个目录,并设置权限(要与 Nginx(Apache)等指定的一样)。

# 保证属组可读写
umask 002
mkdir -p /var/www/wordpress/htdocs
chown nginx:nginx -R /var/www/wordpress/htdocs

配置文件

Rsync 服务端的守护进程运行时配置选项在 /etc/rsyncd.conf

这些选项参数影响身份验证、访问、日志和可用模块。

运行 Vi 编辑器来编辑:vi /etc/rsyncd.conf

原始的 Rsync 服务器设置如下所示:

Rsyncd配置原样

从上图可知悉,当前的 Rsync 器并没有生效,因为所有配置都注释着。

配置文件的格式

该文件由模块和参数组成,模块之外是全局参数,全局参数影响着守护进程的操作和行为,也影响着每个模块,然而一些参数在模块中如果设置的话会覆盖相应全局参数的值。

模块以方括号的模块名称开始,一直持续到下一个模块开始。模块包含的参数格式 name = value。

参数中只能有一个等号,等号、模块和参数名称中周围和内部的空白会被忽略。比如:参数 secrets file = /etc/rsyncd.passwd,与 secretsfile=/etc/rsyncd.passwd 无区别。

任何行以 “#” 开头都被忽略,空行(即使仅包含空格)也是如此。

等号后面的值都是字符串(不需要引号)或布尔值,可以是 yes/no、1/0,或者是 true/false。布尔值中的大小字不敏感。

经本文修改后的配置

我们就把原有选项的注释取消掉,然后再修改和添加一些选项进去,让服务端正常启动并可用。

修改后的服务端配置如下:

uid = nobody
gid = nobody
use chroot = yes
max connections = 10
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
exclude = lost+found/
transfer logging = yes
timeout = 800
ignore nonreadable = yes
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 *.tar.xz *.tar.gz

[wphtmod]
    uid = nginx
    gid = nginx
    path = /var/www/wordpress/htdocs
    read only = false
    write only = true
    list = true
    auth users = wprsync, wprsync2
    secrets file = /etc/rsyncd.passwd
    strict modes = false

全局参数详解

  1. uid:默认是 nobody。 运行守护进程的系统用户 ID,可以是 ID,也可以是用户名。

    传输成功后所属用户就是此用户。

  2. gid:默认是 nobody。gid 是系统用户组的 ID,也可以是用户组的名称。

    传输成功后所属组就是此用户组。

    无论是 uid 或者是 gid,都可以全局设置和在模块中设置,在模块中的设置会覆盖全局设置。

  3. use chroot:如果该参数设置为 “yes”,那么在传输之前先把目录切换到模块中设置的 path 参数指定的目录。

    此举避免了一些安全漏洞。

    它需要 root 权限。

  4. max connections:允许的最大连接数,默认为 0,表示没有限制。

  5. pid file:指定守护进程的 PID 文件所在路径。

  6. log file:指定日志路径。

  7. exclude:排除要传输的目录,模式之间用空格隔开。

    也可以使用“include”参数来覆盖“exclude”参数的效果。

  8. transfer logging:是否启用日志来记录 Rsync 的上传下载。值为 “yes”或“no”。

  9. timeout:指定超时时间。如果在指定时间内没有数据传输, Rsync 会直接退出。单位是秒,默认值为 0 表示永不超时。

  10. ignore nonreadable:是否忽略用户没有访问权限的文件。值为 “yes”或“no”。

  11. dont compress:不压缩传输的文件列表。

    模式之间用空格隔开,支持通配符 * 来指定模式,凡是匹配这些模式都不压缩便传输。

    此参数也可在模块中使用。

其他全局参数:

  1. hosts allow:用于指定允许哪些 IP 或网段客户端访问。可以填写 IP、网段、主机名、域下的主机,IP 之间用空格隔开。默认允许所有人访问。
  2. hosts deny:用户指定的哪些 ip 或网段客户端不允许访问。

    如果 hosts allowhosts deny 具有相同的匹配结果,则客户端最终无法访问。

    如果客户端的地址既不在 hosts allow 中也不在 hosts deny 中,则允许客户端访问。

    默认情况下,所有人可访问。

以上两个参数在模块中亦可一模一样地使用。

模块参数设置

Rsync 的模块配置可以分别指定服务于不同的目录、属主等选项。

  1. wphtmod:模块名,可自定义。
  2. uid:默认是 nobody

    作用与上方全局配置是一样的。

    由于本文中在该服务端仅服务于站点目录,所有要与服务器软件/PHP-FPM指定的用户组一致,因为这才能修改和写入。

    这里的服务器软件运行用户是 nginx,因此该参数除了设置成 nginx,就只能是 root 用户了。说真的,用 root 确实有安全隐患。

  3. gid:默认是 nobody。gid 可以是系统用户组的 ID 或者名称。设为 nginx 的原因与 uid 一致。

    作用与上方全局配置是一样的。

  4. path:指定服务器目录路径。

  5. read only:此参数确定客户端是否能够上传。

    如果该参数为 true,则表示只读,任何尝试的上传都将失败。

    如果参数值为 false,那么只要权限允许,就可以进行上传。默认情况下,所有模块都是只读的。

  6. write only:此参数确定客户端是否能够下载。

    如果该参数为 true,则表示仅写,任何尝试的下载都将失败。

    如果参数值为 false,那么如果权限允许,则可以进行下载。默认情况下,此参数将被禁用。

  7. list:当客户端要求列出可用模块时,此参数确定是否列出此模块。默认为 true

  8. auth users:此参数指定以逗号和/或空格分隔的授权规则列表。

    在最简单的形式中,可以列出将被允许连接到此模块的用户名。

    用户名不需要存在于本地系统中。规则可能包含 Shell 通配符,这些通配符将与客户端提供的用于身份验证的用户名相匹配。

    多个授权用户名可以用逗号+空格隔开。如:auth users = wprsync, wprsync2

    如果设置了“auth users”,则客户端将被要求提供用户名和密码以连接到模块。

    纯文本用户名和密码存储在 secrets file 参数指定的文件中。

    默认情况下,所有用户都可以在没有密码的情况下进行连接(这被称为“匿名 Rsync ”)。

  9. secrets file:指定一个纯文本文件,用来储存与 auth users 授权用户列表中一一对应的密码。

    其内容格式如下:

    username1:passowrd1
    username2:passowrd2
    

    在这里,密码文件位于: /etc/rsyncd.passwd

    此权限要是 600,把属主更改为 Rsync 守护进程的运行用户,并且只能属主可读写。

  10. strict modes:确定是否检查密码文件的权限。

    如果 strict modestrue,那么除了 Rsync 守护程序运行的用户 ID 之外,任何用户 ID 都不能读取用户名-密码对。

    如果参数为 true,则不执行检查。

    默认为 true

    添加此参数是为了适应在 Windows 操作系统上运行的 Rsync 。

…其实还有很多参数可供配置,由于篇幅原因,就不此赘述了

更多的 rsyncd.conf 配置请阅读参考命令行文档 man rsyncd.conf

守护进程

通过选项 --daemon 来启动守护进程:

sudo rsync --daemon

当然也可以把整个启动命令写进 rsyncd.service

修改服务器的默认端口

在配置文件中修改未果,于是根据文档,在 Rsync 的守护进程服务配置中修改:

cat>/lib/systemd/system/rsyncd.service<<EOF
[Unit]
Description=fast remote file copy program daemon
ConditionPathExists=/etc/rsyncd.conf

[Service]
EnvironmentFile=/etc/sysconfig/rsyncd
# ExecStart=/usr/bin/rsync --daemon --no-detach "\$OPTIONS"
# 将上行修改为:
ExecStart=/usr/bin/rsync --daemon --port=6666 --no-detach "\$OPTIONS"

[Install]
WantedBy=multi-user.target
EOF

将端口修改为 “6666”。

执行以下命令使修改生效:

sudo systemctl daemon-reload
sudo systemctl restart rsyncd
sudo systemctl status -l rsyncd

以上修改网络端口号仅适用于 SELinux 禁用状态下。

防火墙开放端口允许进入

  1. FirewallD 防火墙(如果有的话):
    sudo firewall-cmd --permanent --add-port=6666/tcp
    sudo firewall-cmd --reload
    sudo firewall-cmd --list-all
    
  2. 外部或硬件防火墙:

    一些主机提供商会有自己的网络防火墙设置,设置界面基本上是很易用的,读者只需要开放入栈的 TCP 6666 端口即可。


同步本地目录到远程

rsync -v -a --delete --exclude-from=/path/to/exclude/file.list \
--password-file=/path/to/rsync_passwd /path/to/htdocs/ rsync://wprsync@192.168.1.100:6666/wphtmod/

解析一下上述命令的一些参数和值:

  1. -v:表示输出传输过程中输出的一些数据,如若没有指定,那么就没有任何信息输出到屏幕上,基本上等于静默模式;
  2. -a:表示保留创建、修改和访问时间等的元信息,以及表示递归遍历访问;

  3. --delete:当源被删除,在同步后,远程也同步删除,这也是 Rsync 增量备份的基础之一;

  4. --exclude-from:从文件中读取排除的模式。

    当模式匹配到时,对应的文件名将会被忽略。每行代表一个模式,可以有 * 号作为通配符,目录后面不用跟着斜杠。

    像这样:

    .git*
    node_modules
    package.*
    .phpactor.json
    *.cache
    
  5. --exclude:与 --exclude-from 一样,都是设定要排除的模式。

    不同的是其值是一个字符串(仅一个模式的时候),或者有多个值,用花括号 {} 包裹着的字符串列表。

    比如: {'file1.txt', 'dir1/*', 'dir2'}

  6. --password-file: 指定在服务器端由参数 secrets file 指定的密码文件中的密码部分(每行的冒号右边部分)作为内容的本地文件。

    只有一行才是密码,其余行忽略。

    一般赋予 600 权限;

  7. /path/to/htdocs/:表示源目录所在位置,它位于本地计算机上;

    如果路径后面没有斜杠,那么表示将 htdocs 本身上传到指定路径中,而不是上传 htdocs 里面的文件(不包括 htdocs 本身)。

    它将上传到在上文所指定的位置 /var/www/wordpress/htdocs

    于是,如果路径后面没有斜杠,上传后,将放在 /var/www/wordpress/htdocs/htdocs,这不是作者想要的。

    这就是源目录后面有斜杠与没有斜杠的区别。

    这个问题读者做做实验就明白了。

  8. rsync://wprsync@192.168.1.100:6666/wphtmod/:

    1. rsync://:表示用 rsync 协议;
    2. wprsync:表示服务端在模块中由auto users设置的授权用户名,此用户名不是系统的用户名,只是用来验证登录远程 Rsync 服务的名字;

    3. 192.168.1.100:目标服务器的 IP 地址,指向该 IP 地址的域名也行;

    4. 6666:表示 Rsyncd 接收文件数据的本地网络端口,指定未分配的其他数字也可以;

    5. wphtmod:模块名,这也是由服务端设置的,决定上传到哪个位置,在服务端模块中由 path 指令指定。

根据以上的各种参数配置,本地 htdocs 将会 上传到服务器的 /var/www/wordpress/,即形成站点根目录 /var/www/wordpress/htdocs

更多的参数配置请参阅命令行文档: man rsync


踩坑实录

在要进行增量备份的时候,千万不要在源目录路径的后面加上通配符(像下面的命令那样),若是做了这件事,--delete 此参数就不起作用了,读者切记!

rsync -v -a --delete --exclude-from=/path/to/exclude/file.list\
--password-file=/path/to/rsync_passwd /path/to/htdocs/* rsync://wprsync@192.168.1.100:6666/wphtmod/

这时候用 /path/to/htdocs/ 代替 /path/to/htdocs/星号 才是想要的效果:

rsync -v -a --delete --exclude-from=/path/to/exclude/file.list\
--password-file=/path/to/rsync_passwd /path/to/htdocs/ rsync://wprsync@192.168.1.100:6666/wphtmod/

使用效果

首次同步

首次同步要把整个源上传到服务器上面:

正在进行本地到远程的传输

首次同步完成

完成本地到远程的同步

源增加文件

首次同步之后,运行同步命令,会将增加或修改的文件会同步更新到服务器。

Rsync的增量备份

删除

同步删除文件:

Rsync的差异备份


同步远程目标到本地

如果服务器端的配置 write only 的值不为 true,则可以执行以下的命令从远程下载文件:

rsync -v -a --delete --exclude-from=/path/to/exclude/file.list\
--password-file=/path/to/rsync_passwd \
rsync://wprsync@192.168.1.100:6666/wphtmod/ /path/to/htdocs/

利用 Rsync 从本地复制备份到本地

不需要守护进程

rsync -av --delete --exclude-from=/path/to/exclude/file.list /path/to/origin /path/to/dest

实际上是把远程目标更换成本地目标就行了。


后记

长篇大论终于到了最后面。

这里就提醒一下,修改完服务器端的配置文件,记得重启一下守护进程,如用到 SystemD,那就使用 sudo systemctl restart rsyncd 命令来重启。

经过上述方式重启后,即使一些配置有错误,也不会影响它重启,更不会显示在 systemctl status -l rsyncd 命令的执行结果中。

所以,如果要验证重启进程是否成功,可以在客户端尝试执行一次本地到远程的同步命令。

后面作者可能还会继续探索一下 rsync 的参数选项,以及来一篇关于通过 InotifyWait 进行实时文件的备份和传输。


程序知路

鉴于本人的相关知识储备以及能力有限,本博客的观点和描述如有错漏或是有考虑不周到的地方还请多多包涵,欢迎互相探讨,一起学习,共同进步。

本文章可以转载,但是需要说明来源出处!

本文使用的部分图片来源于网上,若是侵权,请与本文作者联系删除: admin@icxzl.com